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-libcomme unique owner PostgreSQL ; - ajouter
tokio-postgres 0.7.18comme driver async natif avec uniquement la featureruntime; - ajouter
deadpool-postgres 0.14.2comme pool avec uniquementrt_tokio_1; - ajouter Refinery
0.9.2avec uniquement son supporttokio-postgres; - utiliser Tokio
1.53.1uniquement 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
NoTlscomme choix initial explicite ; - embarquer
V1__initial_sources.sqlvia Refinery ; - créer uniquement
knowledge_sourcesetknowledge_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é.