DIMA is a framework to identify attempts to exploit cognitive biases in information flow.
The matrix is divided into four phases (Detect — Inform — Memorise — Act). Each phase contains tactics (TAxxxx) which exploit cognitive biases, themselves implemented as techniques (TExxxx).
Source of truth: one Markdown file per phase, under DETECT/,
INFORM/, MEMORISE/ and ACT/.
| Vous voulez… | Allez voir |
|---|---|
| Parcourir la matrice dans le navigateur | DIMA Navigator |
| Lire le détail d'une phase | DETECT/DETECT.md, INFORM/INFORM.md, MEMORISE/MEMORISE.md, ACT/ACT.md |
| Convertir Markdown ↔ JSON | Section Convertisseur Python ci-dessous |
| Bâtir un rapport de campagne PDF / JSON | Section Rapport de campagne ci-dessous |
| Auto-héberger le navigateur (Docker) | Section Image Docker ci-dessous |
Une mini-application HTML, hébergée sur GitHub Pages, qui rend la matrice sous la forme de 4 colonnes colorées (orange / bleu / violet / vert) et charge dynamiquement les JSON par phase :
🔗 https://m82-project.github.io/DIMA/
Fonctionnalités :
- Recherche globale (id, nom, description) avec compteur de résultats live.
- Clic sur une technique → panneau détail (description complète + sections Exemples, Références, Fondements psychologiques, etc.).
- Sélection d'un sous-ensemble de techniques pour bâtir un rapport de campagne (voir plus bas).
- Export PDF de la matrice complète via le bouton PDF : une feuille de
style
@media printrepagine en noir-sur-blanc, A4, une phase par page. - Responsive : 4 colonnes → 2 colonnes → 1 colonne selon la largeur.
L'app est un fichier unique : docs/index.html.
Les données viennent de docs/data/<PHASE>.json, régénérées
automatiquement par la CI à chaque push qui touche les Markdown sources.
python -m http.server 8000 --directory docs
# puis ouvrir http://localhost:8000(Un simple double-clic sur docs/index.html ne marche pas : fetch()
refuse le schéma file://.)
Use case : un analyste observe une opération d'influence et veut documenter quelles techniques DIMA y ont été employées.
- Dans le SPA, cocher la case à gauche du nom de chaque technique
observée.
- La case à droite de chaque tactique coche/décoche toutes ses techniques d'un coup (état mixte représenté par un trait horizontal).
- La sélection persiste en
localStorage(survivre à un refresh).
- Cliquer le bouton Rapport dans l'en-tête.
- Remplir le formulaire : nom de campagne, période d'observation, contexte général, et une observation libre par technique.
- Choisir un export :
- Imprimer / PDF — feuille de style print dédiée : un titre en h1, métadonnées, contexte général dans un encart, puis chaque technique avec sa description complète + sections + l'observation analyste mise en évidence en jaune.
- Exporter JSON — téléchargement d'un fichier nommé d'après le titre de campagne (slugifié), contenant le payload complet.
- Importer JSON — recharge un rapport précédent pour le modifier (ignore les IDs inconnus si la matrice a évolué).
src/dima_convert.py est un script standalone (zéro
dépendance hors stdlib) qui fait office de pivot entre les formats.
Tout passe par uv. L'en-tête PEP 723 du
script permet uv run direct, sans environnement à provisionner.
# 1. Markdown -> JSON (à côté de chaque .md source)
uv run src/dima_convert.py md2json --all
# 2. JSON -> Markdown (pour reformatter le markdown depuis le JSON)
uv run src/dima_convert.py json2md --all
# Mono-fichier
uv run src/dima_convert.py md2json DETECT/DETECT.md -o /tmp/detect.json
uv run src/dima_convert.py json2md /tmp/detect.json -o /tmp/detect.md{
"phase": "ACT",
"tactics": [
{
"id": "TA0041",
"name": "Valorisation individuelle",
"description": "Tactique qui valorise…",
"sections": [],
"techniques": [
{
"id": "TE0411",
"name": "biais d'excès de confiance",
"description": "Surestimation…",
"sections": [
{ "title": "Exemples", "items": ["…", "…"] },
{ "title": "Références", "text": "…" }
]
}
]
}
]
}Round-trip stable : parse → render → parse produit un JSON identique,
testé sur les 4 fichiers réels du repo.
Les 4 fichiers de phase suivent la même convention (voir PR #39) :
- Titres :
# TAxxxx : Nomet## TExxxx : Nom(espace-deux-points-espace). - Liens sources :
[source](url)en fin de description. - Sous-sections :
**Titre:**suivi d'un texte libre et/ou d'une liste à puces. - Pas de doublon d'identifiant TA/TE entre phases.
uv sync --group dev # premier lancement
uv run pytest # parser, round-trip, CLIUne image Docker dédiée permet aussi de lancer la suite sans installer Python (voir Image Docker).
Le SPA se déploie clé en main via une image GHCR construite par la CI :
# Récupère la dernière version et la sert sur http://localhost:8080
docker run --rm -p 8080:8080 ghcr.io/m82-project/dima:latestUne image-sœur embarque pytest et le code source pour faire tourner les tests dans un environnement reproductible :
# Joue toute la suite
docker run --rm ghcr.io/m82-project/dima:latest-tests
# Filtre, mode verbeux, etc. (le CMD par défaut est `pytest -v`)
docker run --rm ghcr.io/m82-project/dima:latest-tests pytest -v -k roundtrip| Évènement | Image runtime | Image tests |
|---|---|---|
push sur main |
ghcr.io/m82-project/dima:latest |
ghcr.io/m82-project/dima:latest-tests |
push d'un tag v1.2.3 |
ghcr.io/m82-project/dima:v1.2.3 |
ghcr.io/m82-project/dima:v1.2.3-tests |
- L'image runtime est multi-arch (
linux/amd64+linux/arm64). - L'image tests est
linux/amd64uniquement (pas la peine d'émuler arm64 juste pour pytest). - Les deux flux ne s'écrasent jamais : un merge sur
mainrafraîchit:latest, un tagvX.Y.Zpublie cette version sans toucher à:latest.
# Image runtime
docker build -f docker/Dockerfile -t dima:dev .
docker run --rm -p 8080:8080 dima:dev
# Image tests (le pytest s'exécute pendant le build : échec = build cassé)
docker build --target tests -f docker/Dockerfile -t dima-tests:dev .
docker run --rm dima-tests:devLe Dockerfile est multi-stage :
builder— regénèredocs/data/*.jsondepuis les.mdsources avec le script Python (stdlib only, pas depip installdans cette étape).tests— installe pytest et joue la suite. LeRUN pytestcasse le build si un test échoue.runtime—nginxinc/nginx-unprivileged:alpinequi sert sur le port 8080 avec unnginx.confcustom (gzip, no-cache HTML/JSON, cache long sur assets statiques).
Workflows GitHub Actions :
| Workflow | Déclencheurs | Rôle |
|---|---|---|
tests.yml |
push main, PR main |
Exécute pytest sur Python 3.10 / 3.11 / 3.12. |
pages.yml |
push main touchant docs/, les .md ou le script |
Régénère docs/data/*.json depuis les .md puis déploie docs/ sur GitHub Pages. |
docker.yml |
push main, tag v*, PR touchant docker/ ou les sources |
Build & push runtime (multi-arch) et tests (amd64) vers GHCR — voir Image Docker. |
create-release.yml |
tag v* |
Publie la release et attache l'archive ZIP du plugin Chrome. |
DETECT/ INFORM/ MEMORISE/ ACT/ # sources Markdown (un .md par phase)
src/
dima_convert.py # convertisseur md ↔ json
tests/test_dima_convert.py # suite pytest
docs/
index.html # SPA navigator
data/<PHASE>.json # JSONs servis sur Pages
docker/
Dockerfile # multi-stage : builder + tests + runtime
nginx.conf # config nginx servant la SPA
.github/workflows/ # CI / CD
pyproject.toml # config uv + pytest
contact : contact@M82-project.org