Files
archicratie-edition/docs/TOPO_LOGIQUE_METIER.md
Archicratia cb4cd01409
Some checks failed
CI / build-and-anchors (push) Failing after 33s
docs: add topo logique métier
2026-01-20 17:04:28 +01:00

8.0 KiB
Raw Blame History

Topo Logique métier de loutil éditorial (Web Edition ↔ Gitea ↔ apply-ticket ↔ CI)

Ce document explique ce que fait réellement loutil, pourquoi il existe, et comment le maintenir sans casser la promesse centrale : citabilité durable + édition traçable + intégration sûre.

Public visé : “commun des mortels” (nouveau contributeur, mainteneur occasionnel, moi dans 6 mois).


0) La promesse (le “pourquoi”)

On veut un site (Astro) où chaque paragraphe est :

  • citable (URL + ancre stable),
  • corrigeable (ouvrir un ticket pré-rempli depuis le paragraphe),
  • réparable de manière sûre (appliquer la proposition dans les sources sans magie),
  • vérifié automatiquement (tests + build + garde-fous en CI).

En bref :
Lecture → proposition → ticket → application → tests → build → publication
…sans perdre la traçabilité, ni casser les citations historiques.


1) Glossaire (pas de jargon sans définition)

  • Ancre : partie #... dune URL (ex : #p-8-0e65838d). Le navigateur saute à lélément HTML portant cet id.
  • Paragraphe citable : un <p id="p-...">...</p> dans larticle.
  • Ticket / Issue : demande de correction sur Gitea (ex : #14).
  • PR (Pull Request) : “demande dajout / fusion” : une proposition de merge dune branche vers master.
  • CI : tests automatiques exécutés sur le serveur à chaque push/PR.
  • Runner : machine/conteneur qui exécute la CI (chez nous : DS220+ / ds220-runner).
  • DEV : npm run dev (serveur Astro à la volée, pas de dist/).
  • BUILD / PROD-like : npm run build puis servir dist/ (ce qui ressemble à la prod).

2) Vue densemble : le pipeline (la “machine éditoriale”)

2.1 Le flux humain (ce que fait léditeur)

  1. Lire une page sur “Archicratie Web Edition”.
  2. Sur un paragraphe : cliquer Proposer.
  3. Choisir Type (Correction / Fact-check) + Category (lexique, style, etc.).
  4. Gitea souvre en nouvel onglet avec un ticket pré-rempli.
  5. Léditeur écrit la proposition, justifie, et valide le ticket.

2.2 Le flux technique (ce que fait la machine)

  1. apply-ticket récupère le ticket via lAPI Gitea.
  2. Il retrouve le bon fichier source (MDX) + le bon paragraphe (matching sûr).
  3. Il applique la modification (ou refuse si trop incertain).
  4. On lance npm test → build + test ancres + check JS inline.
  5. On commit / push.
  6. La CI revalide automatiquement sur le serveur.

3) Composant A — Le site (Astro) et les outils de paragraphe

Dans le rendu final, chaque paragraphe important reçoit un id de forme :

  • p-<index>-<hash8>
    ex : p-8-0e65838d

Ensuite, un script ajoute des outils de paragraphe (“para-tools”) :

  • : lien direct sur le paragraphe (ancre)
  • Citer : copie une citation (titre + version + URL sans query-string)
  • Proposer : ouvre la modale (2 étapes), puis ouvre le ticket Gitea

Point crucial : progressive enhancement

  • Si JS marche : UX optimale.
  • Si JS casse : le site reste lisible, et le lien de proposition reste utilisable au minimum via href.

4) Composant B — Contrat des tickets (machine-readable)

Pour que apply-ticket puisse travailler, le ticket doit rester structuré.

Le ticket contient des lignes “clé: valeur” (une par ligne), par ex :

  • Chemin: /archicratie/prologue/
  • URL locale: http://localhost:4321/archicratie/prologue/#p-...
  • Ancre: #p-8-...
  • Version: ...
  • Type: type/correction (ou type/fact-check)
  • State: state/recevable (ou state/a-sourcer)
  • Category: cat/lexique (optionnel)

Règle dor : ces clés doivent rester simples, stables, sur une ligne chacune.
Sinon, scripts + CI + auto-labeling deviennent fragiles.


5) Composant C — apply-ticket (appliquer sans magie)

apply-ticket fait 4 choses :

  1. Fetch : récupère le ticket via API (FORGE_TOKEN requis).
  2. Parse : extrait Chemin/Ancre/Proposition/(Texte actuel si présent).
  3. Match : retrouve le paragraphe dans le fichier source (MDX) :
    • idéal : “Texte actuel (copie exacte…)” → match fort
    • sinon : match par score → si score trop faible, refus (sécurité)
  4. Apply : modifie le fichier source, sans casser le reste.

Mode sûr

  • --dry-run : montre BEFORE/AFTER, nécrit rien
  • mode normal : écrit + propose ensuite git diff, git add, git commit

6) Composant D — Citabilité P0 : ancres, churn test, aliases

6.1 Le problème

Si lID dépend du contenu, modifier un paragraphe peut changer lID.
Donc une citation historique ...#ancien casse.

6.2 La solution robuste (“web native”)

On ne “résout” pas lancre : on la fait exister.

On maintient un fichier :

  • src/anchors/anchor-aliases.json

Exemple (par page/chemin) : en json { "/archicratie/prologue/": { "p-8-e7075fe3": "p-8-0e65838d" } }

Au build, un script injecte dans dist/.../index.html :

...

Résultat :

le navigateur résout #p-8-e7075fe3 sans JS.

6.3 Pourquoi un fallback JS existe encore ?

En mode npm run dev, on ne passe pas par dist/, donc pas dinjection build-time. Le fallback JS est un filet :

utile en DEV,

utile si un alias manque,

mais pas la solution principale.

7) Tests & garde-fous (qualité automatique)

7.1 npm test doit rester “simple et vrai”

Il exécute :

npm run build (génère dist)

npm run test:anchors (stabilité des ancres)

node scripts/check-inline-js.mjs (évite les scripts inline invalides)

7.2 test:anchors (baseline + churn)

tests/anchors-baseline.json = snapshot de référence.

check-anchors compare dist à la baseline.

Si trop de churn → échec (donc on voit la casse).

On met à jour la baseline uniquement quand on accepte consciemment la nouvelle réalité : npm run test:anchors:update

8) DEV vs BUILD : comprendre sans se tromper

npm run dev → serveur Astro “live”, pas de dist/ ⇒ les alias build-time nexistent pas ⇒ fallback JS peut sactiver.

npm run build && npx serve dist → rendu final “prod-like” ⇒ alias injectés ⇒ citations historiques fonctionnent sans JS.

Repère immédiat :

port 4321 = DEV

port 3000 (serve dist) = PROD-like

9) Rituels opérationnels (les 3 recettes)

Recette 1 — Créer un ticket propre

Cliquer “Proposer”

Choisir Type + Category

Dans Gitea : compléter “Proposition (remplacer par)” + “Justification”

Ne pas détruire les lignes Chemin / Ancre / Type / State / Category

Recette 2 — Appliquer un ticket

en bash : node scripts/apply-ticket.mjs --dry-run node scripts/apply-ticket.mjs git diff npm test git add ... git commit -m "edit: apply ticket # (#)" git push

Recette 3 — Quand un ID change (citabilité)

trouver ancien id + nouveau id

ajouter alias dans src/anchors/anchor-aliases.json

npm run build

vérifier ...#ancien → scroll sur le bon paragraphe

npm test

10) Règles dor (invariants non négociables)

Ne jamais éditer dist/ à la main (artefact).

Ne jamais sacrifier lancre : Chemin + Ancre doivent exister.

Tickets toujours “parsables” (clés stables ligne-par-ligne).

apply-ticket doit pouvoir refuser quand cest ambigu.

npm test doit rester “le bouton rouge” fiable.

11) Dépannage rapide

401 invalid token : FORGE_TOKEN absent ou mal exporté.

Header invalid value : token collé avec des caractères parasites (espaces, retours, texte autour).

Proposer ouvre 2 onglets / remplace la page : bug dinterception click → vérifier preventDefault + stopPropagation et l“openInNewTab”.

Ancien #id ne marche plus :

en PROD-like : vérifier alias injecté + JSON

en DEV : normal que fallback JS soit requis

12) Où lire quoi (docs)

docs/QUICKSTART.md : démarrer vite

docs/MANUEL_REFERENCE.md : usage complet + procédures

docs/CONTRAT_TICKETS.md : format strict des issues

(ce doc) docs/TOPO_LOGIQUE_METIER.md : la logique qui relie tout