Format ouvert · savia-decision-record/v1

La décision, enregistrée. Pas seulement la donnée.

Les organisations humanitaires conservent leurs données et leurs résultats. Presque aucune ne conserve la décision elle-même : les chiffres dont on disposait ce jour là, le raisonnement suivi, la personne qui a tranché, la date. Deux ans plus tard, la réponse dépend de la mémoire de quelqu'un. Le registre de décision comble exactement ce vide, dans un format ouvert que n'importe qui peut lire et vérifier sans SAVIA.

01 / PRINCIPE

Ce qu'un enregistrement contient

Chaque semaine enregistrée dans SAVIA produit une pièce datée. Elle est écrite une fois et ne se modifie plus. Une correction ne remplace jamais une pièce existante : elle en ajoute une nouvelle, qui renvoie à la précédente.

ChampContenu
specIdentifiant du format, ici savia-decision-record/v1.
rangPosition dans le registre, à partir de 1.
identifiantRéférence lisible de la pièce, par exemple SDR-20260829-0007.
precedentEmpreinte de la pièce précédente, ou la chaîne « origine » pour la première.
emis_leHorodatage ISO 8601 en temps universel, plus le fuseau local.
typedecision_hebdomadaire ou resultat_constate.
programmeNom, profil, lieu et période concernés.
auteurQui a pris la décision, avec son rôle.
mesuresLes chiffres réellement disponibles ce jour là.
baremeVersion du calcul, pondérations et seuils appliqués à ce moment.
scoreValeur obtenue sur 100 et verdict correspondant.
risques_documentesRisques notés et, pour les risques critiques, leur justification écrite.
decisionLa décision, écrite par la personne qui l'a prise.
actionsActions déclenchées, responsables, échéances.
resultatCe qui a réellement été constaté après, renseigné plus tard par une pièce dédiée.
empreinteSHA-256 de la pièce, tous champs sauf celui ci.
Pourquoi le barème est enregistré avec la décision

Une organisation peut changer ses pondérations ou ses seuils au fil du temps. Sans mémoire du barème, un score ancien devient illisible. En conservant la règle appliquée ce jour là, la pièce reste interprétable quinze ans plus tard.

02 / INTÉGRITÉ

Empreinte et chaînage

Chaque pièce porte une empreinte SHA-256 calculée sur son propre contenu, et contient l'empreinte de la pièce précédente. Les pièces forment donc une chaîne.

Ce que cela produit concrètement

Modifier un chiffre dans une décision passée change son empreinte, et la vérification le signale immédiatement. Recalculer l'empreinte pour masquer la modification ne suffit pas : la pièce suivante contient encore l'ancienne valeur, et la chaîne se rompt à cet endroit. Supprimer une pièce du milieu rompt également la chaîne.

Autrement dit, réécrire proprement l'histoire suppose de reconstruire toutes les pièces postérieures. Sur un registre exporté et transmis à un bailleur, c'est impossible sans que la copie du bailleur cesse de correspondre.

Le calcul se fait sur l'appareil

L'empreinte est calculée localement, sans réseau et sans service tiers. Une pièce peut donc être créée et signée hors connexion, sur un téléphone de terrain, puis synchronisée plus tard.

03 / EXEMPLE

Une pièce complète

Voici un enregistrement réel dans sa forme exportée. Les valeurs sont fictives, la structure ne l'est pas.

{
  "spec": "savia-decision-record/v1",
  "rang": 7,
  "identifiant": "SDR-20260829-0007",
  "precedent": "9f4c2ae1d7b03e58c1a6f0d9b2e74c8153ab6d0f27e9c41a8b3d5e6f0a1c2b3d4",
  "emis_le": "2026-08-29T14:51:10.482Z",
  "fuseau": "Africa/Niamey",
  "type": "decision_hebdomadaire",
  "organisation": "Nom de l'organisation",
  "programme": {
    "nom": "Appui nutritionnel Diffa",
    "profil": "nutrition",
    "lieu": "Diffa, Niger",
    "periode": "S35 2026"
  },
  "auteur": {
    "nom": "Responsable de programme",
    "role": "manager",
    "identifiant": "prenom.nom@organisation.org"
  },
  "mesures": {
    "kpi_pct": 70,
    "risques_critiques": 2,
    "actions_urgentes": 4
  },
  "bareme": {
    "version": "3-1-1/v1",
    "poids": { "kpi": 40, "risques": 30, "actions": 30 },
    "seuils": { "stable": 80, "pression": 50 }
  },
  "score": { "valeur": 78, "sur": 100, "verdict": "SOUS PRESSION" },
  "indice_risque": 2.4,
  "risques_documentes": [
    { "id": "acces", "intitule": "Acces humanitaire", "note": 4,
      "justification": "Axe Bosso ferme depuis le 24 aout, deux sites non atteints." }
  ],
  "decision": "Maintien du cap. Renforcement du suivi hebdomadaire sur les deux districts en tension.",
  "actions": [
    { "intitule": "Reouvrir le corridor d'approvisionnement",
      "responsable": "Coordination terrain",
      "echeance": "2026-09-06", "statut": "open" }
  ],
  "concerne": null,
  "resultat": null,
  "application": "SAVIA V8.5",
  "empreinte": "c81b7f0a5d2e39461fbc8a0d7e5342196c0ba8df41e729c3506d8fa1b47e0c92"
}
04 / VÉRIFICATION

Vérifier un registre sans SAVIA

La vérification n'exige aucun outil de notre part. Elle tient en cinq étapes et se réécrit en quelques lignes dans n'importe quel langage.

// 1. retirer le champ "empreinte" de l'objet
// 2. serialiser en JSON canonique : cles triees par ordre alphabetique,
//     a tous les niveaux, aucun espace, aucun retour a la ligne
// 3. calculer SHA-256 de cette chaine, en UTF-8, resultat en hexadecimal minuscule
// 4. comparer au champ "empreinte" : toute difference = enregistrement modifie
// 5. verifier que "precedent" vaut l'empreinte de l'enregistrement de rang n-1
//     (ou la chaine "origine" pour le rang 1)

import json, hashlib

def canonique(v):
    return json.dumps(v, sort_keys=True, separators=(",", ":"), ensure_ascii=False)

def verifier(registre):
    attendu = "origine"
    for e in registre:
        corps = {k: v for k, v in e.items() if k != "empreinte"}
        calc = hashlib.sha256(canonique(corps).encode("utf-8")).hexdigest()
        if calc != e["empreinte"]: return "contenu modifie au rang %s" % e["rang"]
        if e["precedent"] != attendu: return "chaine rompue au rang %s" % e["rang"]
        attendu = e["empreinte"]
    return "registre intact"

Un bailleur, un auditeur ou un chercheur peut donc contrôler lui même un registre qu'on lui remet, sans nous demander la permission et sans nous faire confiance.

05 / LIMITES

Ce que ce format ne fait pas

Un format honnête énonce ses limites. Celles ci sont réelles et nous ne les contournons pas par le vocabulaire.

Il ne prouve pas que les chiffres étaient justes

Le registre atteste qu'une décision a été prise sur la base de chiffres précis, à une date précise, par une personne précise. Il n'atteste pas que ces chiffres reflétaient la réalité du terrain. C'est une garantie de traçabilité, pas de véracité.

Ce n'est pas une signature électronique au sens juridique

L'empreinte protège contre la modification silencieuse. Elle ne constitue pas une signature qualifiée au sens du règlement eIDAS ou d'un droit national équivalent, et nous ne la présentons pas comme telle.

L'horodatage est celui de l'appareil

La date provient de la machine qui crée la pièce. Un ancrage sur une source de temps indépendante est prévu dans une version ultérieure du format. Tant qu'il n'existe pas, nous ne prétendons pas le contraire.

La chaîne est propre à une installation

Le chaînage garantit la cohérence interne d'un registre. Il ne relie pas entre eux les registres de deux organisations différentes.

06 / USAGE

Le format est libre

La spécification est publique et son usage est libre. Toute organisation, tout éditeur de logiciel, tout laboratoire de recherche peut produire, lire ou vérifier des enregistrements dans ce format, sans licence à demander et sans dépendance envers SAVIA.

Nous le souhaitons ainsi. Un format de registre n'a de valeur que s'il est partagé, et une organisation ne devrait jamais avoir à choisir entre garder la trace de ses décisions et rester libre de son outil.

Les remarques, corrections et propositions d'extension sont bienvenues à contact@savia-humanitarian.org. Les versions futures resteront compatibles en lecture avec la v1.

Voir un registre se construire

Ouvrez SAVIA, saisissez une semaine, enregistrez la. La première pièce apparaît dans l'onglet Registre, avec son empreinte, et vous pouvez l'exporter immédiatement.

Lancer l'application