0.0.4-alpha.2

This commit is contained in:
2026-10-01 11:00:00 +02:00
parent b55eb23dc0
commit 095ac37d08
19 changed files with 863 additions and 47 deletions

279
deltas/0.0.4/alpha.2.md Normal file
View File

@@ -0,0 +1,279 @@
<!-- file: deltas/0.0.4/alpha.2.md -->
<!-- version: 1 -->
# Delta 0.0.4-alpha.2 — owner PostgreSQL, pool et première migration
## Baseline requise
Partir de `0.0.4-alpha.1` validée et historisée `PASS` :
```text
version précédente 0.0.4-alpha.1
history requis history/0.0.4/alpha.1.md = PASS
stable autoritaire v0.0.3
owner décidé knowledge-store-postgres-lib
driver décidé tokio-postgres
pool décidé deadpool-postgres
migrator décidé Refinery
```
Le history `alpha.1` doit être committé et poussé avant application du présent delta.
La version devient :
```text
0.0.4-alpha.2
```
## Objet
Matérialiser la première frontière PostgreSQL réelle sans encore raccorder les launchers ou les cas d'usage applicatifs :
- créer `knowledge-store-postgres-lib` comme unique owner PostgreSQL ;
- ajouter `tokio-postgres 0.7.18` comme driver async natif avec uniquement la feature `runtime` ;
- ajouter `deadpool-postgres 0.14.2` comme pool avec uniquement `rt_tokio_1` ;
- ajouter Refinery `0.9.2` avec uniquement son support `tokio-postgres` ;
- utiliser Tokio `1.53.1` uniquement comme runtime de test ;
- recevoir URL PostgreSQL et taille du pool par configuration injectée ;
- ne jamais lire de secret depuis l'environnement dans la crate produit ;
- construire un pool borné et conserver `NoTls` comme choix initial explicite ;
- embarquer `V1__initial_sources.sql` via Refinery ;
- créer uniquement `knowledge_sources` et `knowledge_source_sync_state` ;
- exposer une application explicite des migrations ;
- prouver le chemin sur un PostgreSQL réel isolé par schéma temporaire.
Git reste l'autorité du contenu publié. Cette tranche ne stocke ni corps de contenu, ni credential Git, ni compte, proposition, job, index ou projection finale.
## Dépendances retenues
```text
tokio-postgres 0.7.18 default-features = false, features = ["runtime"]
deadpool-postgres 0.14.2 default-features = false, features = ["rt_tokio_1"]
refinery 0.9.2 default-features = false, features = ["tokio-postgres"]
tokio 1.53.1 dev only, features = ["macros", "rt-multi-thread"]
```
Aucun ORM, TLS backend supplémentaire ou abstraction multi-SGBD n'est introduit.
## Contrat public
La façade crate-root est limitée à :
```text
PostgresStoreConfig
PostgresStore
PostgresStoreError
```
Les types `tokio-postgres`, Deadpool et Refinery restent privés à l'implémentation.
`PostgresStoreConfig` ne fournit aucun getter public de l'URL et n'implémente volontairement pas `Debug`. L'URL peut contenir des credentials et ne doit pas être exposée dans les erreurs ou logs.
## Premier schéma
```text
knowledge_sources
source_id TEXT PRIMARY KEY
family TEXT NOT NULL CHECK pgr/howto/snippet/project_local
git_reference TEXT NOT NULL
knowledge_source_sync_state
source_id TEXT PRIMARY KEY REFERENCES knowledge_sources ON DELETE CASCADE
last_synchronized_revision TEXT NOT NULL
```
Refinery possède sa table technique de suivi des migrations. Aucune autre table métier n'est créée.
## Scope des fichiers
REPLACE :
```text
VERSION
Cargo.toml
README.md
RULES.md
docs/architecture/001-PROJECT_PROFILE.md
docs/architecture/002-KNOWLEDGE_ARCHITECTURE.md
docs/plans/004-V0_0_4_POSTGRES_FOUNDATION_PLAN.md
docs/studies/008-V0_0_4_POSTGRES_FOUNDATION_STUDY.md
docs/validation/001-VALIDATION_MATRIX.md
```
ADD :
```text
crates/knowledge-store-postgres-lib/Cargo.toml
crates/knowledge-store-postgres-lib/src/lib.rs
crates/knowledge-store-postgres-lib/src/config.rs
crates/knowledge-store-postgres-lib/src/error.rs
crates/knowledge-store-postgres-lib/src/store.rs
crates/knowledge-store-postgres-lib/unit_tests/config.rs
crates/knowledge-store-postgres-lib/tests/postgres_migration.rs
crates/knowledge-store-postgres-lib/migrations/V1__initial_sources.sql
deltas/0.0.4/alpha.2.md
```
DELETE : aucun.
Aucun fichier sous `Web/`, les trois launchers, `knowledge-app-lib`, `knowledge-domain-lib`, `knowledge-git-api`, `knowledge-git-lib` ou `knowledge-sync-api` n'est modifié.
Aucun history `0.0.4-alpha.2` n'est inclus : il doit refléter uniquement la gate opérateur réelle.
## Précondition PostgreSQL de la gate
La gate réelle nécessite une base PostgreSQL de test accessible avec les droits de créer et supprimer un schéma. Fournir l'URL uniquement dans l'environnement opérateur :
```bash
export KNOWLEDGE_POSTGRES_TEST_URL='postgresql://...'
```
Ne jamais versionner cette valeur.
Si `KNOWLEDGE_POSTGRES_TEST_URL` est absent ou si PostgreSQL n'est pas joignable, arrêter la gate et classer la tranche `BLOCKED`. Ne pas convertir cette absence en `PASS` ou en test ignoré.
## Gate opérateur
Exécuter depuis la racine du dépôt après application du delta.
### Version, history précédent et scope
```bash
test "$(cat VERSION)" = '0.0.4-alpha.2'
grep -F 'version = "0.0.4-alpha.2"' Cargo.toml
test -f history/0.0.4/alpha.1.md
grep -A2 '^## Statut$' history/0.0.4/alpha.1.md | grep -Fx 'PASS'
git ls-files --error-unmatch history/0.0.4/alpha.1.md >/dev/null
test -z "$(git status --short -- history/0.0.4/alpha.1.md)"
test -d crates/knowledge-store-postgres-lib
test -f crates/knowledge-store-postgres-lib/migrations/V1__initial_sources.sql
test -f deltas/0.0.4/alpha.2.md
test ! -e history/0.0.4/alpha.2.md
test -z "$(git status --short -- Web crates/knowledge-pgr-server crates/knowledge-howtos-server crates/knowledge-snippets-server crates/knowledge-app-lib crates/knowledge-domain-lib crates/knowledge-git-api crates/knowledge-git-lib crates/knowledge-sync-api)"
git diff --check
```
### Dépendances, façade et configuration
```bash
grep -F 'tokio-postgres = { version = "0.7.18", default-features = false, features = ["runtime"] }' crates/knowledge-store-postgres-lib/Cargo.toml
grep -F 'deadpool-postgres = { version = "0.14.2", default-features = false, features = ["rt_tokio_1"] }' crates/knowledge-store-postgres-lib/Cargo.toml
grep -F 'refinery = { version = "0.9.2", default-features = false, features = ["tokio-postgres"] }' crates/knowledge-store-postgres-lib/Cargo.toml
grep -F 'tokio = { version = "1.53.1", default-features = false, features = ["macros", "rt-multi-thread"] }' crates/knowledge-store-postgres-lib/Cargo.toml
test "$(grep -c '^pub use crate::' crates/knowledge-store-postgres-lib/src/lib.rs)" -eq 3
grep -Fx 'pub use crate::config::PostgresStoreConfig;' crates/knowledge-store-postgres-lib/src/lib.rs
grep -Fx 'pub use crate::error::PostgresStoreError;' crates/knowledge-store-postgres-lib/src/lib.rs
grep -Fx 'pub use crate::store::PostgresStore;' crates/knowledge-store-postgres-lib/src/lib.rs
! grep -R -n -E 'std::env|KNOWLEDGE_POSTGRES_TEST_URL' crates/knowledge-store-postgres-lib/src
! grep -R -n -E 'println!|eprintln!|dbg!' crates/knowledge-store-postgres-lib/src
grep -F 'max_pool_size' crates/knowledge-store-postgres-lib/src/config.rs
grep -F 'deadpool_postgres::Manager::new' crates/knowledge-store-postgres-lib/src/store.rs
grep -F 'deadpool_postgres::Pool::builder' crates/knowledge-store-postgres-lib/src/store.rs
grep -F 'tokio_postgres::NoTls' crates/knowledge-store-postgres-lib/src/store.rs
grep -F 'run_async(client)' crates/knowledge-store-postgres-lib/src/store.rs
```
### Migration et test ciblé
```bash
grep -F 'CREATE TABLE knowledge_sources' crates/knowledge-store-postgres-lib/migrations/V1__initial_sources.sql
grep -F "CHECK (family IN ('pgr', 'howto', 'snippet', 'project_local'))" crates/knowledge-store-postgres-lib/migrations/V1__initial_sources.sql
grep -F 'CREATE TABLE knowledge_source_sync_state' crates/knowledge-store-postgres-lib/migrations/V1__initial_sources.sql
grep -F 'REFERENCES knowledge_sources(source_id) ON DELETE CASCADE' crates/knowledge-store-postgres-lib/migrations/V1__initial_sources.sql
grep -F 'last_synchronized_revision TEXT NOT NULL' crates/knowledge-store-postgres-lib/migrations/V1__initial_sources.sql
! grep -E -i '\b(content|body|credential|account|proposal|job)\b' crates/knowledge-store-postgres-lib/migrations/V1__initial_sources.sql
grep -F '#[ignore = "requires KNOWLEDGE_POSTGRES_TEST_URL"]' crates/knowledge-store-postgres-lib/tests/postgres_migration.rs
grep -F 'CREATE SCHEMA' crates/knowledge-store-postgres-lib/tests/postgres_migration.rs
grep -F 'DROP SCHEMA' crates/knowledge-store-postgres-lib/tests/postgres_migration.rs
```
### Markdown puis séquence Rust
```bash
python3 -B scripts/audit_markdown_headers.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts deltas history
python3 -B scripts/audit_markdown_links.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts deltas history
python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts deltas history
cargo fmt --all
cargo fmt --all -- --check
python3 -B scripts/audit_rust_test_layout.py crates
python3 -B scripts/audit_rust_blank_lines.py crates
python3 -B scripts/audit_rust_item_spacing.py crates
python3 -B scripts/audit_rust_module_order.py crates
python3 -B scripts/audit_rust_trait_import_blocks.py crates
python3 -B scripts/audit_rust_reexport_blocks.py crates
python3 -B scripts/audit_rust_crate_root_facades.py crates
python3 -B scripts/audit_rust_export_completeness.py --root . --summary-only
cargo metadata --format-version 1 --no-deps > /tmp/sasedev-knowledge-0.0.4-alpha.2-metadata.json
cargo check --workspace
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test -p knowledge-store-postgres-lib
cargo test --workspace --all-targets --all-features
```
### Composition workspace
```bash
python3 -c 'import json; from pathlib import Path; m=json.loads(Path("/tmp/sasedev-knowledge-0.0.4-alpha.2-metadata.json").read_text()); expected={"knowledge-app-lib","knowledge-domain-lib","knowledge-git-api","knowledge-git-lib","knowledge-sync-api","knowledge-web-lib","knowledge-pgr-server","knowledge-howtos-server","knowledge-snippets-server","knowledge-store-postgres-lib"}; assert len(m["workspace_members"]) == 10; assert {p["name"] for p in m["packages"]} == expected; print("Knowledge 0.0.4-alpha.2 workspace audit: clean")'
```
### PostgreSQL réel obligatoire
```bash
test -n "${KNOWLEDGE_POSTGRES_TEST_URL:-}"
cargo test -p knowledge-store-postgres-lib --test postgres_migration -- --ignored --nocapture
```
Si la première commande échoue ou si le test ne peut pas joindre PostgreSQL, arrêter ici et reporter `BLOCKED` avec le transcript obtenu.
### Hygiène, lockfiles et staging
```bash
python3 -c 'from pathlib import Path; roots=[Path("README.md"),Path("RULES.md"),Path("ROADMAP.md"),Path("CHANGELOG.md"),Path("Cargo.toml"),Path("VERSION"),Path("docs"),Path("prompts"),Path("deltas"),Path("history"),Path("crates")]; allowed={".md",".rs",".toml",".sql"}; paths=[p for r in roots for p in ([r] if r.is_file() else r.rglob("*")) if p.is_file() and (p.name == "VERSION" or p.suffix in allowed)]; bad=[str(p) for p in paths if (lambda b: b"\r" in b or not b.endswith(b"\n") or b.endswith(b"\n\n") or any(line != line.rstrip(" \t") for line in b.decode("utf-8").splitlines()))(p.read_bytes())]; assert not bad, bad; print(f"Knowledge 0.0.4-alpha.2 text hygiene: clean ({len(paths)} file(s))")'
test -f Cargo.lock
git check-ignore -q Cargo.lock
if git ls-files --error-unmatch Cargo.lock >/dev/null 2>&1; then echo 'Cargo.lock must remain untracked for Knowledge' >&2; exit 1; fi
test -f Web/knowledge-template-lab/package-lock.json
git diff --quiet -- Web/knowledge-template-lab/package-lock.json
git add -A
git diff --cached --check
git status --short
```
## Transition
### PASS
Produire séparément :
```text
history/0.0.4/alpha.2.md
```
avec les résultats réellement observés. Après application du history, commit/push `0.0.4-alpha.2`, puis préparer `0.0.4-alpha.3` pour la persistance minimale de source et d'état de synchronisation.
### FAIL
Produire le history réel et le committer avant correction. Une erreur bornée de code, manifest, migration ou test utilise `0.0.4-alpha.2.fix.1`.
### BLOCKED
Si seul le PostgreSQL réel requis est indisponible, historiser `BLOCKED` sans prétendre que la gate a passé. Ne modifier ni le code ni l'architecture tant qu'aucun défaut n'est démontré ; reprendre la même preuve dès qu'un PostgreSQL de test est disponible.
### REPLAN
Replanifier si la toolchain stable réellement utilisée est incompatible avec les versions retenues, si l'isolation par schéma n'est pas fiable ou si l'ownership PostgreSQL doit être changé.