Skip to main content
Un fait (Fact, table facts) est ce que Haki considère vrai à un instant donné : « les factures sont en français ». Contrairement à un événement, un fait est versionné et muté au fil du temps — via des transitions de statut explicites, jamais par écrasement silencieux.

Les six statuts

FactStatus
Créé par le Consolidator, pas encore actif. État initial de tout nouveau fait (create_fact, status=candidate, version=1).
FactStatus
Servi par /v1/context. Un seul fait actif par (subject, predicate) en régime normal.
FactStatus
Remplacé par un fait plus récent (supersedes_id pointe le nouveau). Reste dans l’historique, n’est plus jamais servi comme actuel.
FactStatus
Contesté — soit par un POST /v1/feedback rating=incorrect, soit perdant d’un conflit non résolu qui redevient conflictuel. Non servi par le Context Assembler (filtre de statut).
FactStatus
Oublié de façon réversible (POST /v1/forget, mode=disable).
FactStatus
Effacement réel, terminal — aucune transition sortante n’est autorisée. Pose aussi recorded_to (fin bitemporelle système).

Graphe des transitions autorisées

Appliqué par transition_fact_status (app/ledger/core.py) ; toute tentative hors de ce graphe lève illegal_status_transition (422).
candidate → superseded existe spécifiquement pour la résolution de conflits (sprint 6) : le fait perdant d’un ConflictSet est typiquement encore candidate, et le résoudre le fait passer directement à superseded — voir Conflits.
Chaque transition incrémente version de 1.

Champs complets d’un fait

Vue de lecture complète (FactOut, utilisée par GET /v1/facts) :

Typologie et volatilité

La plupart des faits périment en silence — le sujet déménage, change d’emploi, termine un projet — et rien ne vient jamais contredire l’ancienne valeur. fact_kind classe CE QU’EST le fait (attribute : un état du monde ; preference : comment le sujet veut que les choses se passent ; instruction : une règle opératoire durable énoncée par le sujet, à la troisième personne — jamais une directive adressée à l’agent lui-même, rejetée à la porte d’écriture). volatility classe À QUELLE VITESSE il périme sans événement correctif : L’horloge est coalesce(last_reinforced_at, valid_from, recorded_from) : un nouvel événement réaffirmant exactement la même valeur la rafraîchit (renforcement à l’écriture, voir Consolidator) sans créer de nouvelle version du fait. Un fait périmé n’est jamais supprimé ni supersédé — seule sa présentation dans /v1/context change ; il reste visible via GET /v1/facts. Le prédicat n’est pas une clé stable garantie : deux formulations différentes du même concept (bike_count vs bikes_owned) peuvent coexister si l’extracteur les nomme différemment d’un appel à l’autre. C’est précisément le problème que règle la correspondance sémantique du Consolidator — voir Consolidator.

Référence API — Faits et traces

GET /v1/facts, filtrage par statut, limite 200.