Files
sasedev-knowledge/deltas/0.0.4/alpha.2.md
2026-10-01 11:00:00 +02:00

12 KiB

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 :

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 :

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

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 à :

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

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 :

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 :

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 :

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

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

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é

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

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

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

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

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 :

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é.