ISNAD Scientific Platform

Documentation Center
V1 · Référence officielle

Architecture

ISNAD Scientific Platform — Audit de l’ingestion et architecture cible

23 min de lectureMis à jour le 3 novembre 2026
Sur cette page

Date des observations : 3 novembre 2026
Référentiel inspecté : oboutj7/isnad-app-fr, branche master, commit 8a2503a
Périmètre : audit et conception uniquement ; aucune migration, aucun import, aucune écriture de production.

Statut des énoncés#

  • OBSERVÉ : constat issu du code, du schéma ou d’une requête en lecture seule sur la base rattachée.
  • TESTÉ : comportement démontré par une commande exécutée pendant l’audit, généralement sur fixture ou base jetable.
  • PROPOSÉ : architecture, estimation ou critère à valider ; ce n’est pas une capacité existante.
  • NON VÉRIFIÉ : information inaccessible ou preuve insuffisante.

Le fichier audit-artifacts/live-db-2026-11-03.json est la trace brute des mesures de base. Il est produit par scripts/audit/audit-ingestion-live.mjs, dans une transaction PostgreSQL READ ONLY. Les comptes constituent une photographie, pas un résultat scientifique de qualité.


ISNAD ne part pas de zéro. Le dépôt contient déjà un corpus public, un référentiel transversal de narrateurs, des assertions et preuves, des projections de commentaires, des traductions versionnées et une publication humaine. Le problème central n’est donc pas l’absence de modèle scientifique, mais l’absence d’un orchestrateur unique et durable reliant les capacités existantes.

Les constats les plus importants sont :

  1. L’import OpenITI actuel est synchrone et monolithique. Une route HTTP acquit, segmente, écrit le staging et canonise dans une transaction, puis lance une extraction de domaine « best-effort » dont l’échec est absorbé. src/app/api/admin/openiti/import/route.ts:14-42 ; src/server/openiti/import-runner.ts:51-54,112-138,273-310.
  2. La classification et l’extraction OpenITI sont spécialisées. Le classifieur reconnaît surtout des titres et URI de rijāl ; les autres ouvrages restent UNCLASSIFIED. src/server/openiti/prepare.ts:152-162.
  3. Le moteur canonique générique existe mais n’est pas exposé en production. DefaultKnowledgeAcquisitionEngine, ObservedAcquisitionRunner et HadithCorpusProjector sont couverts par des tests, sans route applicative de production trouvée. Les bindings nécessaires sont vides dans la base observée.
  4. Le corpus OpenITI n’alimente pas le corpus public générique. Les 15 126 hadiths publics ont corpus_id = NULL, et chaque hadith possède exactement une chaîne dans l’état actuel. Cela ne démontre pas que les sources ne contiennent qu’une chaîne ; cela décrit uniquement la projection stockée.
  5. La résolution des identités reste incomplète. Sur 47 206 crosswalks, 6 665 sont matched, 3 195 ambiguous et 37 346 unresolved. Les 777 maillons publics sans narrator_id sont un autre périmètre, à ne pas additionner aux crosswalks.
  6. Les traductions et commentaires sont réels, mais leurs statuts doivent rester explicites. Les 2 772 traductions de notices comprennent 1 139 REVIEWED et 1 633 COMPLETE_UNREVIEWED. Les 18 274 versions de traduction de commentaires se répartissent également entre états machine et publiés ; une ligne publiée n’est pas une preuve de revue humaine.
  7. Le contrôle qualité incrémental n’a pas démarré sur la base liée. quality_engine_state et quality_decisions sont vides. Les 32 data_quality_snapshots ne prouvent pas l’exécution de ce moteur particulier.
  8. L’atelier OCR/traduction possède une conception robuste mais non déployée ici. Le code gère leases, retries, budgets et fencing, mais aucun schéma book_workshop n’existe dans la base inspectée. src/infrastructure/book-workshop/postgres/worker.ts:36-83,132-183,187-214.

Décision recommandée : conserver les modèles scientifiques et construire une couche d’orchestration par runs, étapes, artefacts et tâches persistantes. Ne pas créer un second corpus public, une table générique de personnes ni un nouveau silo de traduction.


A1. Méthode, accès et limites#

Éléments effectivement inspectés#

  • dépôt local, historique Git, branches locales et liste distante ;
  • routes, services, domaines, adaptateurs et scripts d’import ;
  • migrations présentes dans supabase/migrations ;
  • schéma PostgreSQL réel dans public et openiti ;
  • comptes, statuts, couverture des chaînes, traductions, alignements et volumes ;
  • suites de tests ciblées et vérification TypeScript.

Limites explicites#

  • NON VÉRIFIÉ : l’historique distant supabase_migrations.schema_migrations est refusé par les privilèges disponibles. Il est donc impossible de certifier l’ordre d’application des migrations.
  • OBSERVÉ : aucun dossier supabase/functions ni configuration de cron n’a été trouvé dans le dépôt. Cela ne prouve pas l’absence de planificateurs configurés hors du dépôt.
  • NON VÉRIFIÉ : aucun test de bout en bout n’a été réalisé contre l’application publique ou les routes d’administration déployées.
  • NON VÉRIFIÉ : l’audit n’établit ni la licence effective des témoins OpenITI ni la justesse scientifique des contenus extraits.
  • OBSERVÉ : GitHub expose 100 branches. Les branches locales feat/openiti-commentary-import et chore/retire-idrap-fr-legacy n’ont pas de commit ou diff propre par rapport à master. Le contenu exclusif des 98 autres branches distantes n’a pas été audité exhaustivement.
  • Le dépôt contient des modifications utilisateur préexistantes. Elles ont été lues mais ni modifiées ni annulées.

A2. Architecture actuelle#

Interface admin OpenITI
  └─ POST /api/admin/openiti/import (synchrone, maxDuration 300 s)
      └─ runImport
          ├─ GitHub : URI → métadonnées → version → texte
          ├─ analyse mARkdown : entrées, pages, offsets, SHA-256
          ├─ staging openiti.stg_*
          ├─ fonction SQL openiti.canonicalize_import
          └─ extraction de domaine hors transaction, best-effort
              └─ pont narrateur exact-normalisé → external_narrators/crosswalk/assertions

Pipeline canonique générique, actuellement surtout testé
  CorpusAdapter/SourceReader
    → DefaultKnowledgeAcquisitionEngine
    → HadithCorpusProjector / adaptateurs spécialisés
    → corpus public, rijāl ou commentaires
  ObservedAcquisitionRunner → import_batches + dataset_acquisition_bindings

Services séparés
  traductions de notices / commentaires / atelier OCR
  publication éditoriale humaine / journaux / contrôles qualité

Références principales : src/server/openiti/import-runner.ts:1-10,273-320, supabase/migrations/20260905130000_openiti_auto_ingestion_support.sql:39, src/infrastructure/knowledge-acquisition/ObservedAcquisitionRunner.ts:1-32,99-193.

A3. Inventaire des quinze domaines demandés#

DomaineConstat observableTables, dépendances et limitesRéutilisation
1. Dépôt et branchesmaster à 8a2503a, synchronisé avec origin/master ; 100 branches distantesPas d’inventaire fonctionnel exhaustif des branches distantes autresBase de travail conservée ; modifications utilisateur protégées
2. ApplicationNext.js, routes Node et consoles admin séparéesImport synchrone via src/app/api/admin/openiti/import/route.ts:5-42Authentification admin et pages réutilisables
3. MigrationsNombreuses migrations couvrant corpus, identités, traductions, commentaires et OpenITIHistorique d’application distant inaccessibleConserver les contraintes et journaux ; aucune réécriture historique
4. Schéma réelSchémas public et openiti ; pas de book_workshopVues comprises dans l’inventaire des colonnes ; certaines anciennes tables supposées sont absentesLe schéma réel prime sur les noms historiques du code
5. Async et planificationFiles et leases dans le code de l’atelier ; aucune Edge Function ou cron trouvéeAtelier non déployé ; processing_runs ne constitue pas une file généraleReprendre les principes de lease, fencing et budgets
6. OpenITIAcquisition GitHub, version choisie, texte brut, empreintes, offsets, staging et canonisationsrc/server/openiti/prepare.ts, metadata-resolver.ts, github.ts, analyze.ts, import-runner.tsExcellent socle d’acquisition et de localisation
7. Catalogue éditorial10 œuvres, toutes PUBLISHED / UNVERIFIED ; publication humaine avec verrou optimisteopeniti.work_publication, work_publication_events ; src/server/openiti/publication.ts:84-193Réutiliser sans automatiser la publication
8. Hadiths et isnād15 126 hadiths, 15 126 chaînes, 87 060 maillons ; aucun hadith sans chaîne, aucun avec plusieurs chaîneshadiths, hadith_chains, hadith_chain_nodes ; toutes les lignes ont corpus_id = NULLProjecteur canonique réutilisable, mais projection actuelle limitée
9. Normalisation arabeNormalisation légère OpenITI et normalisations distinctes pour recherche, identité et matnsrc/server/openiti/markdown.ts:239-251, src/domain/tradition-variant/MatnMatching.ts:43-75, src/domain/narrator-identity/NameRepresentation.ts:16-57Préserver le verbatim et versionner chaque fonction ; ne pas unifier aveuglément
10. Identités de narrateursGénération de candidats, preuves, variantes et décisions ; pont OpenITI conservateurPont exact sur normalized_name_ar, aucune création canonique : src/server/openiti/narrator-bridge.ts:1-25,212-279Réutiliser le référentiel et enrichir la résolution multisource
11. Rijāl et correspondances43 935 notices, quatre sources ; crosswalks et relations présentsknowledge_entries, narrator_assertions, narrator_relation_assertions, narrator_crosswalk*Réutiliser les notices sans fusionner les personnes
12. Traduction françaiseOrchestrateur idempotent, versionné par hash arabe ; revue humaine distinctesrc/server/rijal-translation/translationOrchestrator.ts:71-140 ; tables knowledge_entry_translations, commentary_translationsRéutiliser les contrats ; les raccorder aux tâches durables
13. CommentairesDeux sources, 2 974 documents, 14 018 passages, 11 395 alignementscommentary_* ; adaptateur canonique Fatḥ limité à une tranche : CommentaryCorpusAdapter.ts:74-120,123-197Conserver passages, preuves, cibles et alignements révisables
14. Qualité et provenanceSources, datasets, batches, hashes, locators, journaux ; quality engine vide52 batches, 352 runs ; aucune liaison dataset_acquisition_bindingsConsolider la télémétrie, ne pas remplacer les preuves scientifiques
15. OCR et imports externesAtelier OCR/traduction et scripts spécialisés Fatḥ, Nawawi, Ibn HajarAtelier absent de la base ; scripts/ibnhajar/load-from-openiti.cjs:121-132 supprime puis réinsère sous --applyRéutiliser les patterns, isoler les traitements destructifs historiques

A4. Mesures réelles de la base rattachée#

Toutes les valeurs de cette section sont OBSERVÉES dans audit-artifacts/live-db-2026-11-03.json, clés queries.* et tableCounts.

Corpus public#

MesureValeur
Collections29
Livres155
Chapitres5 240
Hadiths documentaires15 126
Chaînes15 126
Maillons87 060
Hadiths avec zéro chaîne0
Hadiths avec plusieurs chaînes0
Maillons avec narrator_id86 283
Maillons sans narrator_id777
Hadiths avec corpus_id = NULL15 126

Le ratio 86 283 / 87 060, soit environ 99,11 %, mesure uniquement le remplissage de la clé étrangère dans les maillons existants. Il ne mesure ni l’exactitude des identifications ni le rappel d’extraction des chaînes.

Narrateurs et connaissances#

MesureValeur
Narrateurs canoniques14 709
Narrateurs externes47 206
Assertions sur narrateurs132 923
Assertions de relations23 186
Transmissions218 172
Notices de connaissance43 935
Mentions de notices59
Résolutions de mentions59
SourceLiéesAmbiguësNon liées
Al-Kāshif7 14001 228
Tahdhīb al-Kamāl8 47103 093
Tahdhīb al-Tahdhīb1 003010 955
Taqrīb al-Tahdhīb10 2261541 665

Ces statuts sont ceux stockés ; ils ne constituent pas une validation humaine globale.

OpenITI#

MesureValeur
Imports10
Imports COMPLETED8
Anciens imports encore RUNNING2
Œuvres / versions / documents canoniques10 / 10 / 10
Entrées57 362
Faits102 376
Relations23 186
Anomalies de staging3
openiti.knowledge_entry_bindings0
openiti.document_lifecycle_events0

Les deux imports RUNNING datent du 3 septembre, n’ont ni URI d’œuvre ni dates de début/fin. Leur statut stocké ne prouve pas qu’un processus soit encore actif.

Type d’entréeNombre
Notice biographique47 693
Renvoi4 706
En-tête de section4 329
Inconnu634

Les méthodes extractor:* historiques coexistent avec TAHDHIB_HEADER_BEFORE_RAWA_AN_V1, taqrib-grade-span-v1, taqrib-name-boundary-v1 et taqrib-tabaqa-v1. Les 76 602 faits produits par extractor:* sont NEEDS_REVIEW. Le code actuel du pont filtre explicitement sur extractor:* et documente les autres lignes comme héritées : src/server/openiti/narrator-bridge.ts:149-154.

Les cinq œuvres classées sont Taqrīb, Tahdhīb, Lisān al-Mīzān, Taʿjīl al-Manfaʿa et Taʿrīf Ahl al-Taqdīs. Bulūgh al-Marām, al-Iṣāba, al-Majmaʿ al-Muʾassis, Nukat ʿalā Ibn al-Ṣalāḥ et Nukhbat al-Fikar restent UNCLASSIFIED.

Commentaires et traductions#

MesureValeur
Sources de commentaires2
Éditions5
Documents2 974
Passages14 018
Alignements11 395
Cibles9 112
Assertions de passages0
Versions de traduction de commentaires18 274
Décisions de revue de traduction de notices1 139

Fatḥ al-Bārī : 2 973 documents et 11 343 passages. Nawawi : 1 document et 2 675 passages.

AlignementsNombre
EXACT7 964
PROBABLE3 264
CONFLICT146
AMBIGUOUS17
MISSING4

Tous les alignements sont MACHINE_REVIEW_NEEDED, y compris les EXACT. Les 2 974 documents de commentaires sont REVIEW_NEEDED pour les droits et MACHINE_REVIEW_NEEDED pour la vérification.

Les traductions de commentaires comprennent 9 137 lignes MACHINE_REVIEW_NEEDED et 9 137 lignes PUBLISHED pour les mêmes couples de modèles et volumes ; cela correspond vraisemblablement à des versions ou projections distinctes, mais la table de comptage seule ne suffit pas à établir leur cycle de vie. Ne pas conclure à 18 274 textes distincts publiés.

Orchestration et qualité#

  • import_batches : 45 completed, 5 failed, 2 running.
  • processing_runs : 2 PARSER / COMPLETED ; 346 RESOLVER / COMPLETED, 1 RUNNING, 1 FAILED, 2 CANCELLED.
  • dataset_acquisition_bindings : 0.
  • quality_engine_state : 0 ; quality_decisions : 0.
  • data_quality_snapshots : 32.

Les journaux actuels ne sont ni interchangeables ni suffisants pour relancer une étape arbitraire avec ses entrées, versions et artefacts.

A5. Composants réutilisables#

PrioritéComposantPourquoi le conserver
CritiqueRéférentiel narrators et tables de représentations, assertions, relationsC’est l’identité historique transversale ; le pont ne crée volontairement pas de doublon
CritiqueCorpus collections/books/chapters/hadiths/hadith_chains/hadith_chain_nodesModèle public existant, à alimenter par projection plutôt que par corpus concurrent
CritiqueProvenance data_sources/datasets/import_batches, hashes et locatorsBase de la reproductibilité et de la révision
ÉlevéeprepareImport, parseur mARkdown et canonisation SQLAcquisition, offsets, texte original et transaction déjà présents
ÉlevéeContrat CorpusAdapter, moteur et projecteurSéparation déjà conçue entre lecture neutre et persistance
ÉlevéePublication humaine et journal append-onlyVerrouillage optimiste et séparation du statut de vérification
ÉlevéeOrchestrateur de traduction de noticesIdempotence, hash source, contrôles de complétude et concurrence
ÉlevéeAlignements de commentaires et preuvesDistinction exact/probable/conflit et revue
MoyenneAtelier OCR/traductionLeases, fencing, budgets, retries et protection des validations humaines
MoyenneMatnMatchingSignaux explicables de similarité, sans conclusion d’identité : MatnMatching.ts:118-158

A6. Doublons, fonctions manquantes et risques#

Doublons fonctionnels#

  • Deux voies OpenITI coexistent : import openiti.* et adaptateurs du pipeline canonique, sans composition de production.
  • Plusieurs pipelines d’écriture spécialisés coexistent pour hadiths, rijāl, Fatḥ, Nawawi et Ibn Hajar.
  • Plusieurs orchestrations techniques coexistent : openiti.imports, import_batches, processing_runs, jobs de l’atelier.
  • Plusieurs surfaces de traduction existent. Elles répondent à des objets différents, mais n’ont pas d’orchestrateur commun de planification et de coût.

Ces doublons ne doivent pas être supprimés avant cartographie des écritures, dépendances et décisions humaines.

Fonctions manquantes ou non câblées#

  • orchestration générale asynchrone, reprise par étape et annulation contrôlée ;
  • registre des versions de classifieurs, extracteurs, resolveurs et configurations ;
  • classification scientifique générique avec revue et règles de capacité ;
  • extraction générique de collections structurées dans l’import OpenITI principal ;
  • projection OpenITI vers corpus_id et chaînes multiples en production ;
  • gestion explicite des renvois incomplets et graphes de bifurcation/convergence dans le pipeline principal ;
  • gestion des droits dans l’acquisition OpenITI générique ;
  • tableau de bord unique de runs, étapes, coûts, couverture et erreurs ;
  • déploiement du quality engine et de l’atelier dans la base liée.

Risques de régression#

RisqueGravitéMesure obligatoire
Casser les lectures publiques en changeant le corpusCritiqueProjections additives, tests de contrat, rollback applicatif
Fusionner des homonymes ou écraser une décision humaineCritiqueIdentités externes conservées, candidats et preuves, décisions versionnées
Perdre les enrichissements lors d’une réimportationCritiqueIdempotence par contenu et protection des versions revues
Confondre statut technique et qualité scientifiqueCritiqueAxes séparés, publication humaine
Réécrire des données par traitement spécialiséÉlevéeInterdire les suppressions larges dans les nouveaux runners ; dry-run et impact préalable
Timeout HTTP ou double exécutionÉlevéeFile durable, leases, idempotency keys, worker séparé
Coûts IA non maîtrisésÉlevéeBudgets, réservation, quotas, cache par hash et journal d’usage
Croissance du staging et des versionsMoyenneRétention des artefacts dérivés sans supprimer le texte source ; métriques de volume
Dérive entre code et migrationsÉlevéeInventaire réconcilié dans un environnement avec droits de lecture suffisants

Le DELETE FROM ibnhajar.shuyukh du script spécialisé est un risque réel si --apply est utilisé ; il n’a pas été exécuté pendant cet audit. scripts/ibnhajar/load-from-openiti.cjs:121-132.

A7. Tests effectivement exécutés#

CommandeRésultat observéPortée et limite
npm run test:openiti54 tests : 47 réussites, 7 tests DB ignorés, 0 échecNe prouve pas l’intégration à la base distante
npm run test:independent-source-proofRéussite sur PGliteFixture Muslim : chaînes, idempotence, enrichissements
npm run test:independent-source-resilience-proofRéussite sur PGliteReprise et préservation sur environnement jetable
npm run test:e13RéussiteSegmentation, versioning, orchestration et repository de traduction
npm run test:translation-reviewRéussite, y compris PGliteRevue, concurrence, RLS et journaux sur périmètre testé
npm run test:commentary-vertical-sliceRéussite sur 17 passages réels en base jetableIdempotence et rollback d’une tranche, pas du corpus complet
npm run test:commentary-corpus-adapterRéussiteContrat de l’adaptateur Fatḥ
npm run typecheckRéussiteTypage statique uniquement

La preuve indépendante couvre 50 hadiths, 136 chaînes et 577 nœuds sur fixture. Ces chiffres ne sont pas des comptes de production et ne doivent pas être comparés aux 15 126 hadiths publics.


Capacité cibleExistantÉcartDécision cible
Acquisition multisourceOpenITI/GitHub abouti ; autres readers spécialisésPas d’enregistrement générique des fournisseurs et droitsAdaptateurs SourceProvider et manifeste d’acquisition
Conservation originaleTexte en staging, hashes, offsetsCycle de vie et retraitement non unifiésDocument immutable, artefacts et versions de traitement
ClassificationRègles titres/URI de rijālCinq œuvres non classées ; autres genres non couvertsClassifieur de capacités, règles + preuves + revue
Extraction hadithsParseurs canoniques et spécialisésNon connectés à l’import principalPlugin HADITH_COLLECTION vers projecteur existant
Chaînes multiplesReader Muslim sur tranche ; production à une chaîne/hadithCouverture générale non démontréeGraphe de chemins et références explicites, sans inférence cachée
VariantesModèles traditions, tradition_variants, signaux matnPas de preuve d’intégration OpenITI génériqueAssertions de relation avec méthode et preuves
IdentitésCandidats, crosswalks, décisionsPont limité au nom exact normaliséRésolution progressive multisource et files de revue
Rijāl43 935 notices et nombreuses assertionsLien OpenITI canonique videBinding explicite, sans duplication des notices
CommentairesModèle riche et imports réelsAdaptateur générique limité à une tranche FatḥPlugin commentaire avec mêmes tables et preuves
TraductionVersioning et revue robustesPlanification et budgets non unifiésÉtape séparée réutilisant les orchestrateurs
QualitéSnapshots et anomalies ; quality engine videPas de contrôle obligatoire par étapeGates numériques, métriques et rapports signés par version
PublicationHumaine, optimiste, journaliséeNon reliée à un tableau de préparation globalPréconditions calculées, décision admin inchangée
OrchestrationLogs et files spécialisésImport HTTP synchrone ; pas de reprise par étapeRuns + étapes + tâches persistantes + workers
CoûtsBudget dans l’atelierPas de budget général pour toutes traductions/IARéservations, usage, quotas et estimation avant lancement
AdministrationPages import/œuvres/imports/anomaliesPas de reprise sélective ni vision pipelineConsole unique alimentée par le modèle de runs

C1. Principes non négociables#

  1. Un seul référentiel de narrateurs : public.narrators reste canonique ; les mentions externes restent distinctes.
  2. Un seul corpus public : les nouvelles acquisitions projettent dans le modèle existant ; pas de corpus OpenITI concurrent.
  3. Le texte source est immutable ; toute normalisation est un artefact dérivé et versionné.
  4. Une étape produit des artefacts, pas une vérité scientifique implicite.
  5. Une extraction, une déduction et une décision humaine ont des provenances distinctes.
  6. Aucune publication automatique. La publication et la vérification numérique restent des axes éditoriaux distincts.
  7. Toute étape est idempotente et rejouable à périmètre constant.
  8. Aucune suppression historique pendant la migration vers le nouvel orchestrateur.

C2. Flux logique proposé#

Demande admin
  → Acquisition planifiée
  → Document source + métadonnées + droits + empreinte
  → Classification des capacités
  → Segmentation structurelle
  → Extraction spécifique au type
  → Résolution progressive des identités
  → Enrichissement et relations scientifiques
  → Projection dans les modèles canoniques existants
  → Contrôles numériques
  → Traductions optionnelles et budgétées
  → Rapport de préparation
  → Décision humaine de publication

Chaque flèche = dépendance explicite entre étapes persistantes.
Chaque sortie = artefact versionné + provenance + métriques + anomalies.

Un échec de traduction ne remet pas en cause les étapes amont. Une correction d’identité déclenche seulement la résolution, les enrichissements dépendants et les projections affectées.

C3. Composants applicatifs proposés#

ComposantResponsabilitéRéutilisation
IngestionCatalogŒuvres, versions, capacités, état courantopeniti.works, versions, publication
SourceProviderDécouverte et acquisition d’une source autoriséeGitHub/OpenITI prepare.ts, github.ts
DocumentStoreTexte original, métadonnées, droits, hash, localisationstg_documents, documents canoniques
CapabilityClassifierType documentaire et extracteurs applicablesRègles actuelles comme premier fournisseur de signaux
StructureParserSegments, pages, offsets, structure hiérarchiquemarkdown.ts, analyze.ts
DomainExtractorHadiths, chaînes, rijāl, commentairesExtracteurs et readers existants
IdentityResolverCandidats, preuves, ambiguïtés, décisionsDomaines narrator-identity, crosswalks
EnrichmentLinkerRelations, notices, matn, commentairesAssertions, preuves, MatnMatching, alignements
CanonicalProjectorÉcriture idempotente dans corpus/rijāl/commentairesHadithCorpusProjector, repositories actuels
TranslationServiceVersions, statuts, revue, budgetOrchestrateurs de notices/commentaires/atelier
DigitalQualityServiceComplétude, intégrité, couverture, anomaliesSnapshots, issues, quality model
PublicationServiceDécision humaine et journalpublication.ts inchangé fonctionnellement
RunCoordinatorDAG d’étapes, dépendances, reprise, annulationNouveau, alimenté par les journaux existants
WorkerExécution par lot avec lease et fencingPatterns de book-workshop
AdminConsoleSuivi, preuves, anomalies, coûts, actionsPages OpenITI et consoles existantes

C4. Modèle de contrôle proposé#

Les noms ci-dessous sont logiques ; leur implémentation doit être revue avant toute migration.

  • ingestion_run : demande, œuvre/version, périmètre, configuration, état global, demandeur.
  • ingestion_stage : type, dépendances, version de code, entrée hash, état, compteurs, début/fin.
  • ingestion_task : lot, lease, tentative, prochaine exécution, erreur, priorité.
  • ingestion_artifact : sortie adressable, hash, schéma, producteur, métriques, rétention.
  • ingestion_event : transitions append-only et actions humaines.
  • ingestion_budget : plafond, réservation, consommation et coût monétaire observé.
  • ingestion_binding : correspondance explicite entre run et import_batch, processing_run ou import historique.

Clé d’idempotence recommandée : (type_étape, document_sha256, périmètre, version_extracteur, configuration_hash). Les décisions humaines ne font jamais partie des artefacts supprimés lors d’un rejeu.

États techniques#

PENDING → READY → RUNNING → SUCCEEDED, avec FAILED_RETRYABLE, FAILED_FINAL, CANCEL_REQUESTED, CANCELLED, BLOCKED.

Un run techniquement réussi peut produire un rapport scientifique partiel. Cette distinction suit déjà ObservedAcquisitionRunner : src/infrastructure/knowledge-acquisition/ObservedAcquisitionRunner.ts:23-29,178-193.

C5. Contrats scientifiques par famille#

Collections de hadiths#

  • conserver document, livre, chapitre, numéro source, ordre, offsets et verbatim ;
  • modéliser chaque ṭarīq séparément et chaque maillon dans son ordre ;
  • stocker ح, بهذا الإسناد, نحوه, مثله comme objets structurels typés ;
  • représenter une référence non résolue comme telle, sans recopier silencieusement une chaîne précédente ;
  • permettre bifurcations et convergences par chemins, sans déduire une convergence à partir du seul nom ;
  • ne jamais confondre hadith documentaire, tradition, variante et chaîne.

Rijāl#

  • chaque notice reste rattachée à son ouvrage et son édition ;
  • génération de candidats à partir des noms, kunya, nisba, générations, dates et relations ;
  • preuves contradictoires conservées ;
  • correspondance plausible = candidat, jamais identité certaine automatique ;
  • correction d’identité = nouvelle décision et reprojection ciblée.

Commentaires#

  • passages et lemmes liés à leur document source ;
  • cibles déclarées séparées des cibles calculées ;
  • alignements exact/probable/ambigu/conflit conservés ;
  • assertions attribuées à leur autorité avec citation et locator.

Traduction#

  • source arabe et hash obligatoires ;
  • modèle, prompt/profil, version, date, statut et revue obligatoires ;
  • reprise par lots et invalidation par changement de hash ;
  • aucune traduction ne remplace l’arabe ou une version humaine protégée.

C6. Interface administrative cible#

Une page « Ingestions » doit offrir :

  • catalogue et sélection de version, droits et métadonnées ;
  • estimation préalable du périmètre et du coût IA ;
  • graphe d’étapes, progression, durée, retry et annulation ;
  • compteurs distincts documents/hadiths/traditions/variantes/chaînes/maillons ;
  • narrateurs non résolus, candidats, preuves et décisions ;
  • anomalies bloquantes et non bloquantes ;
  • aperçu côte à côte arabe/source/extraction/traduction ;
  • retraitement sélectif avec affichage des dépendances ;
  • rapport qualité et couverture de revue ;
  • action de publication via les règles actuelles.

Ce plan est PROPOSÉ et subordonné à validation. Chaque étape est livrable indépendamment, sans migration destructive.

PrioritéÉtapeContenuCritères d’acceptationDépendances et risques
P0D0. RéconciliationInventaire migrations/déploiement, propriétaires des tables, routes et écrituresMatrice approuvée ; aucun écart non expliqué sur les tables touchéesAccès lecture historique migrations ; modifications utilisateur
P0D1. Contrats et témoinsGeler les modèles d’entrée/sortie, jeux de référence et métriquesFixtures versionnées ; dénominateurs documentés ; baseline reproductibleExpertise scientifique humaine
P0D2. Orchestrateur en shadowRuns, étapes, tâches, artefacts, worker, auth adminReprise après crash, lease expiré, retry, annulation et double clic sans doublonNouvelle couche seulement ; aucun changement de production
P1D3. Adaptateur acquisitionEnvelopper prepareImport sans réécriture ; manifeste droits/version/hashMême document produit même manifeste ; staging existant conservéAPI GitHub et licences
P1D4. ClassificationRegistre de capacités et règles génériques, sortie explicableOuvrage non reconnu bloqué pour revue ; aucun extracteur inappropriéValidation des types et vocabulaire
P1D5. Pilote rijālRaccorder extraction, bindings et résolution progressiveRejeu idempotent ; décisions humaines intactes ; mesures précision/rappelRisque d’homonymies ; gros volumes
P1D6. Pilote collection structuréeProjection additive dans corpus existant avec corpus_id renseignéComptes réconciliés ; rollback logique ; aucune duplication publiqueLectures publiques et index
P1D7. Pilote MuslimṬuruq, ح, renvois, chemins et offsetsJeu de référence complet sur périmètre ; ambiguïtés visiblesNe pas généraliser les règles d’une tranche
P2D8. CommentairesGénéraliser l’adaptateur et réutiliser alignements/preuvesCibles déclarées/calculées distinctes ; 17 passages témoins non régressésVariation des éditions
P2D9. TraductionsTâches séparées, budgets et orchestrateurs existantsÉchec traduction sans rejeu amont ; cache hash ; coût observableTarifs et quotas fournisseurs
P2D10. Qualité et consoleGates, dashboards, reprise sélective et rapportMétriques avec dénominateurs ; publication toujours humaineNe pas transformer score en verdict
P3D11. Extension progressiveNouvelles œuvres par capacité, ramp-up mesuréSeuils E atteints sur trois témoins puis échantillons nouveauxDette des extracteurs spécialisés

Règles de livraison#

  • chaque étape inclut tests unitaires, tests PostgreSQL jetables, test de rejeu et test de rollback logique ;
  • le chemin historique reste disponible jusqu’à preuve de parité sur le périmètre pilote ;
  • les scripts destructifs ne sont pas intégrés au moteur ;
  • aucune généralisation à partir du seul succès d’un test vert ;
  • les changements de schéma sont additifs et accompagnés d’une analyse des lectures/écritures.

E1. Trois témoins#

TémoinRôlePérimètre initial proposé
Collection structurée déjà supportée, p. ex. BukhārīSegmentation, livres/chapitres, hadiths, projection canoniqueUn livre complet choisi et figé, pas un échantillon de commodité
Ṣaḥīḥ Muslim, témoin OpenITI existantChaînes multiples, ح, renvois, variantes et convergencesLa tranche actuelle complète, puis un livre complet avant extension
Taqrīb al-Tahdhīb, puis Tahdhīb en second témoin rijālNotices, grades, renvois, homonymies, résolutionEnsemble complet de notices sélectionnées par strates documentées

Les textes et éditions doivent être épinglés par URI, commit et SHA-256. Les jeux de référence sont relus par des personnes compétentes, avec procédure de désaccord et version.

E2. Jeux de référence#

Chaque cas contient : identifiant source, verbatim, offsets, structure attendue, chaînes/chemins attendus, mentions, rattachements acceptés, ambiguïtés acceptées, variantes et traduction de référence lorsque pertinente.

Prévoir des strates : cas ordinaires, renvois, homonymes, notices courtes/longues, pagination absente, marqueurs inconnus, contradictions et erreurs volontairement injectées.

Aucun chiffre de qualité n’est calculé sur les seules lignes faciles ou déjà résolues.

E3. Indicateurs et dénominateurs#

MesureFormuleDénominateur obligatoire
Précision de segmentationsegments corrects / segments produitsTous les segments produits sur le périmètre
Rappel de segmentationsegments attendus retrouvés / segments attendusRéférence humaine exhaustive du périmètre
Exactitude des limiteslimites exactes / limites attenduesDébut et fin séparés si nécessaire
Rappel des chaînesṭuruq attendus retrouvés / ṭuruq attendusToutes les voies du témoin, y compris renvois
Fidélité des chaîneschemins entièrement exacts / chemins attendusOrdre, narrateurs, formules et références
Précision d’identificationliens automatiques corrects / liens automatiques produitsInclut les faux liens ; exclut seulement les abstentions déclarées
Couverture d’identificationmentions liées / mentions du périmètreToutes les mentions, y compris non résolues
Taux d’ambiguïtémentions ambiguës / mentions du périmètreNe pas assimiler ambiguïté à erreur
Conservation des variantesvariantes attendues conservées / variantes attenduesVariantes et renvois distingués
Exactitude des rattachementsliens source corrects / liens évaluésCibles déclarées et calculées rapportées séparément
Stabilité de rejeusorties identiques / sorties attenduesHash des artefacts et comptes, hors timestamps
Couverture de revueobjets revus / objets publiés du périmètreType d’objet et niveau de revue précisés

Pour la traduction, rapporter séparément complétude mécanique, erreurs de sens, omissions, ajouts, terminologie et taux d’acceptation humaine. Un contrôle automatique n’est pas une validation linguistique ou scientifique.

E4. Tests techniques obligatoires#

  • même entrée exécutée deux fois : aucun doublon, mêmes artefacts logiques ;
  • interruption avant/après commit : reprise sans perte ni double appel non tracé ;
  • lease expiré et deux workers : un seul commit valide ;
  • correction d’extracteur : nouvelle version, ancienne preuve consultable ;
  • correction d’identité : seules les projections dépendantes sont rejouées ;
  • source arabe modifiée : traduction précédente devient obsolète, jamais écrasée ;
  • traduction en échec : extraction et publication antérieure intactes ;
  • publication concurrente : conflit optimiste visible ;
  • source indisponible ou quota IA atteint : état explicite, reprise contrôlée ;
  • aucune décision humaine supprimée par rejeu.

E5. Critères de passage à l’échelle#

Les seuils chiffrés doivent être approuvés après la baseline ; en fixer maintenant serait arbitraire. Conditions minimales :

  1. référence humaine complète et versionnée sur chaque témoin ;
  2. aucun défaut critique ouvert : faux lien silencieux, perte de verbatim, écrasement humain, doublon public ;
  3. précision et rappel publiés avec intervalles, strates et dénominateurs ;
  4. rejeu, interruption, concurrence et retraitement sélectif démontrés ;
  5. coût et durée mesurés par unité documentaire ;
  6. revue des droits et provenance complète ;
  7. publication humaine et rollback logique démontrés.

L’extension se fait par cohorte limitée, avec comparaison à la baseline et arrêt en cas de régression.


F1. Mesures observées#

  • Base PostgreSQL : 2 080 566 419 octets, environ 2,08 GB décimaux ou 1,94 GiB.
  • Texte OpenITI canonique : 21 199 630 caractères ; même total en staging. La duplication logique du texte est donc réelle, sans déduire son coût physique exact du seul nombre de caractères.
  • Documents de commentaires : somme déclarée de 41 091 313 octets.
  • 352 processing_runs et 52 import_batches donnent un historique utile, mais pas une mesure actuelle de débit.
  • Aucun tarif fournisseur, nombre de tokens ou coût réel consolidé n’a été mesuré par cet audit.

F2. Charge de développement — hypothèses#

Ordre de grandeur pour un développeur senior connaissant Next.js/PostgreSQL, avec revue scientifique séparée :

LotHypothèse de charge
D0–D2 : réconciliation, contrats, orchestrateur20–30 jours-personne
D3–D4 : acquisition et classification10–18 jours-personne
D5 : rijāl et résolution18–30 jours-personne
D6–D7 : collections et Muslim25–40 jours-personne
D8 : commentaires10–18 jours-personne
D9–D10 : traduction, qualité, console20–32 jours-personne
D11 : durcissement et extension initiale10–20 jours-personne
Total indicatif113–188 jours-personne

Cette estimation n’est ni un devis ni un engagement. Elle suppose la réutilisation effective des composants ; une refonte du corpus ou des identités la rendrait caduque. La constitution des références humaines peut représenter plusieurs semaines de travail expert et n’est pas comprise dans les jours de développement.

F3. Infrastructure#

PROPOSÉ :

  • PostgreSQL/Supabase pour contrôle, files et données canoniques ;
  • worker Node séparé, à concurrence bornée, sans transaction ouverte pendant un appel IA ;
  • stockage objet pour artefacts volumineux et exports, avec hashes dans PostgreSQL ;
  • secrets uniquement côté serveur, rôles minimaux et audit admin ;
  • métriques de files, latence, erreurs, retries, coûts, saturation et stockage ;
  • environnements jetables pour migrations et tests de rejeu.

Le choix d’hébergement du worker reste ouvert. L’import HTTP actuel ne doit pas devenir le worker long.

F4. Coût IA — modèle paramétré, sans prix inventé#

Pour chaque famille :

coût = Σ (tokens_entrée × prix_entrée + tokens_sortie × prix_sortie)
       + coût OCR éventuel + coût embeddings éventuel

coût_unitaire = coût_total_observé / unités réellement traitées
coût_projeté(N) = N × coût_unitaire / (1 − taux_de_rejeu_ou_échec)

À mesurer sur les trois témoins : caractères et tokens par entrée, contexte ajouté, sortie, taux de retry, taux de cache, modèle et prix à la date d’exécution.

Optimisations : traduction uniquement à hash modifié, lots adaptés, contexte borné, quotas par run, plafond avant lancement, cache et réutilisation des validations humaines. Les traductions existantes ne doivent pas être régénérées pour alimenter une nouvelle orchestration.

F5. Stockage et montée en charge#

Le coût futur dépend de W œuvres, C caractères par œuvre, V versions conservées, A artefacts dérivés et I index/embeddings :

volume_brut ≈ W × C × V + A + I + journaux + sauvegardes

Aucune projection monétaire fiable n’est possible sans tarifs et volumétrie cible. Les risques principaux sont les copies staging/canonique, les embeddings, les index de recherche, les traductions multiversion et les journaux.

Mesures recommandées : artefacts dérivés régénérables, rétention différenciée, partitionnement si mesuré nécessaire, traitement par lots, index surveillés et sauvegardes testées. Le texte original et les preuves ne sont pas des artefacts à purge automatique.


ExistantCibleAction
openiti.imports, stg_*Acquisition + documents + artefactsEnvelopper et lier aux runs
openiti.canonicalize_importStructureParser + canonisation OpenITIConserver initialement
prepare.ts, github.ts, metadata-resolver.tsOpenitiSourceProviderExtraire derrière un port, sans duplication
inferWorkTypeCapabilityClassifierÉtendre avec preuves et revue
Extracteurs extractor:*Plugins rijāl versionnésConserver comme baseline, mesurer
narrator-bridge.tsIdentityResolver initialÉtendre progressivement ; conserver les abstentions
DefaultKnowledgeAcquisitionEngineComposition des adaptateursCâbler au coordinator
ObservedAcquisitionRunnerBinding run/batch et provenanceRéutiliser les principes, pas comme DAG complet
HadithCorpusProjectorProjection du corpus publicRéutiliser et renforcer chaînes multiples
knowledge_entries et assertionsRéférentiel documentaire rijālAucun remplacement
commentary_*Commentaires canoniquesRéutiliser passages, preuves, alignements
translationOrchestrator et revueÉtape traductionOrchestrer sans réécrire le modèle
book_workshop workerWorker patternRéutiliser lease/fencing/budget après déploiement validé
quality_engine_state, quality_decisionsSuivi incrémental qualitéActiver seulement après contrats et tests
openiti.work_publication*Publication humaineConserver la décision et le journal

Approuver ou ajuster, dans l’ordre :

  1. la conservation stricte du corpus et du référentiel existants ;
  2. le modèle d’orchestration par runs/étapes/tâches/artefacts ;
  3. les trois témoins et leurs périmètres exhaustifs ;
  4. les responsables scientifiques des jeux de référence ;
  5. les lots D0 à D2 comme premier incrément, en environnement non productif.

Aucun développement du moteur, migration ou import massif n’est justifié avant cette validation.