PD-295 — Bibliothèque documentaire → mémoire vivante (5 briques incrémentales)¶
1. Contexte¶
Le système ProbatioVault produit de grandes quantités de connaissances au fil du workflow de gouvernance : besoins, spécifications, REX, fiches de veille, clarifications PO, verdicts de gate. Aujourd'hui ces artefacts sont stockés comme une bibliothèque plate indexée par FAISS : chaque document est rangé quelque part, accessible via les 4 skills de recherche (/learnings, /specs, /plans, /contracts), mais la bibliothèque ne vient jamais au-devant d'une nouvelle story. Toute réutilisation de connaissances passée dépend d'un humain ou d'un agent qui va explicitement fouiller.
Deux sources de valeur se perdent totalement :
- Les conversations de clarification PO au step 0 : utilisées sur le moment puis jetées. En mode Ringbearer (L3), elles transitent par
gov_ask_po→ broker → Signal → humain → broker → agent, sans aucune persistance intermédiaire. - Les 128 fiches de veille produites dans
ProbatioVault-doc/docs/veille/2026-*/*.md: lisibles uniquement manuellement, jamais injectées automatiquement au démarrage d'une story qui en bénéficierait.
Par ailleurs, les learnings existants sont traités uniformément : une leçon qui a été réutilisée 10 fois pèse autant qu'une leçon jamais ressortie. Une leçon de février 2026 sur un sujet qui a évolué pèse autant qu'une leçon d'hier.
Source : confrontation de 4 analyses ChatGPT sur l'architecture RAG face à la stack réelle ProbatioVault + inspiration directe de 3 projets mémoire agent publiés entre le 2026-04-08 et le 2026-04-10 (MemPalace, Moerae, GBrain) + validation par le pattern Karpathy LLM Wiki (2026-04-08).
2. Besoin¶
En tant que PO/architecte ProbatioVault, je veux que la bibliothèque documentaire existante se transforme en mémoire vivante qui s'injecte automatiquement au démarrage de chaque story, afin de capitaliser sur les réutilisations mesurées, archiver proprement ce qui est obsolète, et éliminer la dépendance à une recherche manuelle explicite.
3. Principes directeurs¶
- Zéro migration d'outil. FAISS + Ollama + Markdown + YAML restent la stack unique. Pas d'Elasticsearch, pas de pgvector, pas de base graph, pas de SQLite.
- Rien ne remplace l'existant. Les 5 briques s'ajoutent à côté. Les 4 skills de recherche,
learnings.jsonl,specs-index/,/coherence,gov-compounderPhase 5 continuent de fonctionner tels quels. - Refactor incrémental en 5 briques indépendantes ou faiblement couplées, chacune commitable seule, chacune avec ses propres tests de validation.
- Pas de derive d'architecture abstraite. Les 4 analyses ChatGPT proposaient des architectures de plus en plus élaborées (RAG+reranker → moteur documentaire → MARS → moteur cognitif industriel). On retient ~15 % utile, ~85 % hors-scope reporté en candidats séparés G26-G32.
4. Périmètre fonctionnel — 5 briques¶
4.1 [B1] Index FAISS des fiches veille¶
Objectif : rendre les ~128 fiches de ProbatioVault-doc/docs/veille/**/*.md interrogeables par recherche sémantique, avec filtrage par verdict et impact_pv.
Livrables :
scripts/collect-veille.py: parse frontmatter YAML + titre H1 + résumé, écritdata/veille.jsonl. Clone decollect-specs.py.scripts/index-veille.py: embeddings via Ollamanomic-embed-text(768 dim), écritdata/veille-index.faiss+data/veille-embeddings.npy+data/veille-cache.json. Clone deindex-learnings.py.scripts/search-veille.py: clone desearch-learnings.pyavec flags--impact fort|modere|faible,--verdict signal|bruit|veille,--trace STORY_ID..claude/commands/veille-search.md: skill minimal qui invoquesearch-veille.py. À ne pas confondre avec/veille(archivage).- Modification de
scripts/reindex-all.py: ajouter phase veille après contracts/specs/plans.
Schéma data/veille.jsonl :
{
"slug": "2026-04-10-gbrain-thin-cli-sqlite-knowledge-base",
"date": "2026-04-10",
"title": "GBrain — thin CLI + SQLite + MCP",
"tags": ["ia-tooling", "dev-experience", "open-source"],
"verdict": "signal",
"impact_pv": "modere",
"summary": "Garry Tan publie la spec de GBrain...",
"source_path": "2026-04/2026-04-10-gbrain-thin-cli-sqlite-knowledge-base.md"
}
Prérequis : aucun. Indépendant.
4.2 [B2] Index FAISS des clarifications step 0¶
Objectif : capter les réponses PO aux 4 questions de clarification step 0 au lieu de les jeter. Les rendre interrogeables sémantiquement pour les futures stories du même domaine.
Livrables :
- Modification de
.claude/commands/gov-step-0.md: nouvelle Phase 1 bis qui écritPD-XX-clarifications.mddans le dossier epic après la collecte des 4 réponses PO (verbatim, pas de synthèse). scripts/collect-clarifications.py: parcourt/Users/loic/Developpement/ProbatioVault/*/docs/epics/**/PD-*-clarifications.md, parse frontmatter, écritdata/clarifications.jsonl.scripts/index-clarifications.py: clone deindex-learnings.py.scripts/search-clarifications.py: clone desearch-learnings.pyavec filtres--domainet--projectobligatoires (une clarification est très liée à son domaine d'origine)..claude/commands/clarifications.md: skill minimal.- Modification de
scripts/reindex-all.py: ajouter phase clarifications.
Schéma PD-XX-clarifications.md :
---
story: PD-XX
step: 0
date: 2026-04-11
domain: auth-identity
project: backend
---
# Clarifications PO — PD-XX
## Q1 — Problème / besoin utilisateur
{réponse PO verbatim}
## Q2 — Critères de succès
{réponse PO verbatim}
## Q3 — Contraintes connues
{réponse PO verbatim}
## Q4 — Priorités (must-have / nice-to-have)
{réponse PO verbatim}
Prérequis : aucun. Indépendant.
4.3 [B3] Scoring de réutilisation sur learnings.jsonl¶
Objectif : ajouter un champ reuse_score calculé à partir de data/learnings-injections.jsonl (créé par #28 le 2026-04-11). Le score reflète combien de fois un learning a été réinjecté en step 0 ET combien de fois la story receveuse a passé Gate 8 GO.
Formule initiale :
reuse_score = (
nb_injections * 0.4
+ nb_stories_gate8_go_apres_injection * 0.4
+ nb_domains_distincts * 0.2
)
Les 3 coefficients sont à ajuster empiriquement mais le triplet capture (a) la fréquence de réinjection, (b) l'efficacité réelle sur gate 8, © la transversalité cross-domaine.
Livrables :
scripts/compute-learning-scores.py: litlearnings.jsonl+learnings-injections.jsonl+metrics.jsonl, écritdata/learnings-scores.jsonlfichier parallèle, ne touche PASlearnings.jsonlqui reste source immuable.- Modification de
scripts/search-learnings.py: tri secondaire parreuse_scoreaprès la distance FAISS. Flag--min-score Npour filtrer. - Intégration dans
/morning: afficher les 3 learnings les plus réutilisés.
Prérequis : #28 instrumentation (faite le 2026-04-11, commit 076dc3e). Le script est commitable immédiatement mais produira des scores à 0 tant que ~5 stories n'auront pas tourné avec l'instrumentation active.
4.4 [B4] Promotion automatique + éviction des learnings stale¶
Objectif : transformer learnings.jsonl d'un flux append-only plat en un système à 3 niveaux de portée : story, domain, global. Les learnings montent automatiquement quand leur score dépasse un seuil. Les learnings non-utilisés depuis longtemps sont archivés hors de l'index actif.
Schéma étendu learnings.jsonl :
{
"story": "PD-19",
"gate": 3,
"verdict": "NON_CONFORME",
"tags": ["#spec-incomplete"],
"learning": "...",
"date": "2026-02-09",
"scope": "story"
}
Migration : tous les learnings existants passent à scope: story par défaut. La promotion se fait ensuite par script.
Règles de promotion :
reuse_score >= 0.3ETnb_domains >= 1→scope: domainreuse_score >= 0.6ETnb_domains >= 2→scope: global
Règles d'éviction :
nb_injections == 0ETdate > 8 semaines→ déplacer versdata/learnings-archive.jsonl- L'index FAISS n'indexe plus les learnings archivés après la prochaine réindexation
- L'archive reste accessible via grep pour debug historique
Filtrage à l'injection step 0 :
Story dans domaine auth-identity → injecter les scope: story du même domaine + tous les scope: domain du domaine + tous les scope: global. Les scope: story d'autres domaines sont ignorés. Les scope: global sont injectés partout (ils ont prouvé leur valeur cross-domaine).
Livrables :
- Migration initiale de
learnings.jsonl: ajouterscope: storyà toutes les entrées existantes. scripts/promote-learnings.py: applique les règles de promotion, réécritlearnings.jsonl(versionné git = rollback facile).scripts/archive-stale-learnings.py: applique les règles d'éviction.- Modification de
gov-learnings-inject.md+search-learnings.py: filtrage parscopeselon le domaine. - Intégration dans
gov-compounder: appel des 2 scripts après réindexation step 10.
Précaution obligatoire : git add data/learnings.jsonl && git commit avant la migration, pour rollback atomique en cas de problème.
Prérequis : [B3] (fournit les scores).
4.5 [B5] Injection unifiée au step 0¶
Objectif : modifier gov-learnings-inject.md pour qu'au step 0 d'une nouvelle story, il injecte 3 sources dans le contexte initial — learnings pertinents + fiches de veille pertinentes + clarifications passées du même domaine.
Livrables :
- Modification de
.claude/commands/gov-learnings-inject.md: nouvelle Étape 1 « Injection unifiée mémoire » qui orchestre 3 recherches en parallèle (learnings, veille, clarifications) avec--tracesystématique. - Format d'injection : bloc Markdown structuré avec 3 sections distinctes pour que l'agent puisse distinguer les sources.
- Extension de
scripts/analyze-compounding.py: ventilation par source (combien de fois chaque source a été injectée, laquelle corrèle le mieux avec Gate 8 GO v1). - Tests sur une story réelle en mode Ringbearer.
Format du bloc d'injection :
## Mémoire pertinente pour cette story
### Learnings (5 plus pertinents, pondérés par réutilisation)
- [PD-19] [Spec Incomplete] ... (scope: global, score: 0.87)
- [PD-38] [Plan Ambiguity] ... (scope: domain, score: 0.52)
### Veille (3 fiches fort/modéré impact)
- [2026-04-10] GBrain : thin CLI SQLite knowledge base
- [2026-04-08] MemPalace : mémoire Claude palais spatial
### Clarifications passées (même domaine)
- [PD-42, 2026-03-15] Priorités : MFA obligatoire B2B, optionnel B2C
Prérequis : [B1], [B2], [B4].
5. Ordre d'implémentation et dépendances¶
B1 (veille) ──┐
B2 (clarifications) ──┤──> B5 (injection unifiée)
B3 (scoring) ───> B4 (promotion + éviction) ──┘
Ordre recommandé : B1 → B2 → B3 → B4 → B5. B1 et B2 sont indépendantes. B3 débloque B4. B5 unifie tout et dépend de B1 + B2 + B4.
6. Critères de succès — 4 indicateurs mesurables¶
| # | Indicateur | Mesure | Cible |
|---|---|---|---|
| CS-1 | Taux d'itérations de gate | scripts/analyze-compounding.py | Gate 8 GO v1 augmente vs baseline (à mesurer avant/après [B5]) |
| CS-2 | Réutilisation des learnings | Nb learnings injectés au moins 1 fois / total | ≥ 30 % à 3 mois (baseline : 0 %) |
| CS-3 | Capitalisation des clarifications | Nb stories où search-clarifications.py remonte une réponse PO antérieure pertinente | ≥ 1 occurrence par mois post [B2] |
| CS-4 | Activation des fiches de veille | Nb stories où une fiche impact_pv: fort\|modere est injectée automatiquement au step 0 | ≥ 5 occurrences dans les 5 premières stories post [B5] |
7. Hors-scope explicite¶
Pour éviter la dérive d'architecture abstraite, les éléments suivants sont explicitement exclus de PD-295 et reportés en candidats séparés :
- Pas de reranker neural (candidat G27)
- Pas de BM25 hybrid (candidat G28)
- Pas de metadata filter avancé au-delà de
--impact,--domain,--scope(candidat G26) - Pas de knowledge graph de relations entre artefacts (candidat G30)
- Pas de skill router automatique (candidat G32)
- Pas de résumés hiérarchiques pré-générés (candidat G31)
- Pas de refonte de
specs-index/**/*.yaml - Pas de migration FAISS vers autre chose (Elasticsearch, pgvector, SQLite-FTS5)
- Pas de classifier d'intention
- Pas de boucle adaptative de retrieval
- Pas de nouveau moteur de stockage
- Pas de refonte en couches L1/L2/L3/L4
Ces items peuvent revenir dans le TODO si les mesures #28 après [B5] montrent un gap persistant.
8. Contraintes¶
8.1 Techniques¶
- Stack immuable : FAISS 1.x + Ollama + Markdown + YAML. Toute brique qui introduit une dépendance hors de cette stack est rejetée.
- Pipelines externes : aucun (vérifié — 5 scripts internes au repo
ProbatioVault-ia-governancelisentlearnings.jsonl, aucun consommateur externe, parsing défensif avec.get()). L'ajout du champscopeen [B4] est non-breaking. - Rollback : pour toute migration en place (notamment
learnings.jsonlen [B4]), commit git préalable obligatoire pour rollback atomique. - Mode Ringbearer : [B2] doit persister les clarifications avant que
gov_ask_pone rende la réponse à l'agent (sinon perte si le Ringbearer crashe entre la réponse et la rédaction du besoin).
8.2 Process¶
- Plan unique en 5 briques (arbitrage PO 2026-04-11) : PD-295 couvre les 5 briques en un seul plan, un seul verdict Gate 8. L'implémentation peut s'étaler sur 2-3 semaines réelles pour laisser à #28 le temps d'accumuler ~5 stories d'instrumentation.
- Commits attendus : 1 commit par brique, 5 commits au total.
- Effort estimé : 4 jours de travail effectif, étalés sur 2-3 semaines.
8.3 Dépendances amont validées¶
-
28 instrumentation
learnings-injections.jsonl→ fait le 2026-04-11 (commit 076dc3e)¶ -
27
extract-terminal-errors.py→ fait le 2026-04-11 (commit 039b503)¶ - L3 mode Ringbearer via
gov-interact.sh→ fait le 2026-04-11 (commit be1c610)
9. Priorités¶
| Priorité | Briques | Justification |
|---|---|---|
| Must-have | B1, B2 | Indépendantes de #28. ROI immédiat et tangible. Capturent les 2 sources de valeur qui se perdent aujourd'hui. |
| Should-have | B3, B4 | Dépendent de l'accumulation d'instrumentation #28 (~5 stories). Livrables possibles immédiatement mais produiront des résultats utiles progressivement. |
| Must-have (orchestration) | B5 | Cible finale de la story. Dépend de B1+B2+B4. Sans B5, les autres briques restent des capacités passives. |
10. Ce qu'on ne fait pas (rappel)¶
- On ne remplace pas l'existant. Les skills actuels continuent de fonctionner.
- On ne refactore pas
specs-index/. - On ne change pas d'outil de stockage.
- On n'introduit pas de couches hiérarchisées.
- On ne pose pas de classifier d'intention au-dessus de la recherche.
11. Références — projets d'inspiration¶
| Projet | Mécanismes repris | Fiche veille locale |
|---|---|---|
| Moerae (principale) | Segments append-only, lifecycle, promotion auto, éviction stale, HNSW groupé par définition logique. B3+B4 transposent directement ces 5 mécanismes sur FAISS. | 2026-04-10-moerae-memoire-agents-rust-hnsw.md |
| MemPalace (secondaire) | Mémoire conversationnelle persistante → transposée en B2 (clarifications). Non repris : stockage intégral sans compression, organisation wings/rooms/halls. | 2026-04-08-mempalace-memoire-claude-palais-spatial.md |
| Karpathy LLM Wiki (validation) | Pattern markdown-based memory : raw/ = docs/epics/, wiki/ = specs-index/, schema = CLAUDE.md, health check = /coherence. Confirme la direction générale. | 2026-04-08-karpathy-llm-wiki-second-brain-markdown.md |
| GBrain (tertiaire) | Pattern compiled truth + timeline sur SQLite FTS5. Non repris (volume insuffisant pour justifier SQLite). Peut inspirer une évolution future de B4. | 2026-04-10-gbrain-thin-cli-sqlite-knowledge-base.md |
12. Livrables attendus¶
Scripts (tous clones défensifs d'existants)¶
scripts/collect-veille.pyscripts/index-veille.pyscripts/search-veille.pyscripts/collect-clarifications.pyscripts/index-clarifications.pyscripts/search-clarifications.pyscripts/compute-learning-scores.pyscripts/promote-learnings.pyscripts/archive-stale-learnings.py
Scripts modifiés¶
scripts/reindex-all.py(phases veille + clarifications)scripts/search-learnings.py(tri secondaire parreuse_score, flag--min-score, filtrage parscope)scripts/analyze-compounding.py(ventilation par source)scripts/morning-review.sh(top 3 learnings réutilisés — optionnel)
Skills Claude Code¶
.claude/commands/veille-search.md(nouveau).claude/commands/clarifications.md(nouveau).claude/commands/gov-step-0.md(modifié — persistance clarifications).claude/commands/gov-learnings-inject.md(modifié — injection unifiée).claude/commands/gov-compounder.md(modifié — promotion + éviction en fin step 10)
Données¶
data/veille.jsonl(généré)data/veille-index.faiss(généré)data/veille-embeddings.npy(généré)data/veille-cache.json(généré)data/clarifications.jsonl(généré)data/clarifications-index.faiss(généré)data/clarifications-embeddings.npy(généré)data/clarifications-cache.json(généré)data/learnings-scores.jsonl(généré, fichier parallèle)data/learnings.jsonl(migré, ajout champscope)data/learnings-archive.jsonl(généré par éviction)
Documentation¶
- Une entrée dans
DONE.mdpar brique (5 entrées). - REX en step 9 couvrant les 5 briques.
13. Arbitrages déjà tranchés par le PO¶
- Scope PD-295 = 5 briques en un seul plan (2026-04-11). Pas de découpage en PD-295 + PD-296. Un seul Gate 8, une seule story. Étalement 2-3 semaines accepté.
- Aucun risque de casser un pipeline externe (2026-04-11). Vérification exhaustive : 5 scripts internes, parsing défensif, pas de parser strict, ajout de champ non-breaking.
- Précaution [B4] : commit git atomique préalable avant migration
learnings.jsonl.