Files
archicratie-edition/docs/anchors.md
Archicratia b78eb4fc7b
All checks were successful
CI / build-and-anchors (push) Successful in 1m52s
SMOKE / smoke (push) Successful in 11s
docs: normalisation md + diagnostics dedup + LEGACY strict
2026-02-02 12:08:53 +01:00

158 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Contrat des ancres (paragraphes opposables)
## Source de vérité du sélecteur
Le site garantit la citabilité des paragraphes via des IDs injectés sur les balises `<p>`.
**Sélecteur contractuel :**
- `.reading p[id^="p-"]`
Tout outillage (scripts, tests, docs) doit utiliser ce sélecteur comme référence.
## Ce que le test vérifie
Le test compare, page par page, la liste des IDs de paragraphes présents dans `dist/` contre une baseline versionnée.
- Ajouts dIDs : généralement OK (nouveaux paragraphes).
- Suppressions / churn élevé : alerte (risque de casser des citations existantes).
## Fichier baseline
- `tests/anchors-baseline.json`
## Commandes
1) Générer / mettre à jour la baseline (cas intentionnel) :
- `npm run build`
- `npm run test:anchors:update`
2) Vérifier sans changer la baseline (cas normal) :
- `npm run build`
- `npm run test:anchors`
## Politique déchec (pragmatique)
Le test échoue si le churn dune page dépasse un seuil (défaut : 20%) sur une page “suffisamment grande”.
## Aliases build-time
- `src/anchors/anchor-aliases.json`
- `scripts/inject-anchor-aliases.mjs`
- `scripts/check-anchor-aliases.mjs`
- et rappelle : *alias = compat rétro de liens historiques sans JS*
## Ancres de section (H2) quand on utilise `<details>`
Quand un chapitre est structuré en sections repliables (`<details>`), on utilise une ancre “technique” dédiée pour garantir :
- une cible stable même si le H2 est dans un bloc replié,
- un scroll-offset correct (header + bandeau),
- une détection fiable pour le bandeau “reading-follow”.
Contrat côté HTML rendu :
- présence dun élément de type :
- `<span class="details-anchor" id="..."></span>`
- puis, dans le même `<details>`, un H2 visible dans le body.
Contrat côté CSS :
- `.details-anchor` a `scroll-margin-top: var(--sticky-offset)`.
Contrat côté JS (EditionLayout) :
- `openDetailsIfNeeded(el)` ouvre le `<details>` parent si nécessaire avant de scroller.
## Compat “legacy hash” : `#p-<idx>-<hash>`
Un hotfix de compat existe pour les anciennes ancres de paragraphes au format :
- `#p-<index>-<8 hex>`
Si lID exact nexiste plus :
- on cherche le premier élément dont lid commence par `p-<index>-`
- puis scroll avec offset.
But : éviter les “liens morts” historiques quand une régénération dIDs a eu lieu.
Limite : cest un fallback de dernier recours (moins déterministe quun alias explicite).
Le mécanisme recommandé reste : `src/anchors/anchor-aliases.json` + injection au build.
_______________________________________
Dernière mise à jour : 2026-01-29
Ce document formalise comment on évite de casser les liens profonds (URLs avec `#ancre`).
---
## 1) Principe
Les IDs dancres générés (ou dérivés) peuvent changer :
- réécriture
- insertion/suppression de paragraphes
- re-slug dun titre
➡️ Donc : on ne “devine” pas un fallback par index en runtime.
➡️ On fait un aliasing **déterministe à la build**, versionné.
---
## 2) Le mapping dalias
- Fichier versionné (ex) : `src/anchors/anchor-aliases.json`
- Format : `oldId -> newId` par page
Ex en json :
{
"/archicratie/archicrat-ia/chapitre-4/": {
"p-8-ancien": "p-8-nouveau"
}
}
## 3) Injection à la build (dans dist)
Script : scripts/inject-anchor-aliases.mjs
Moment : postbuild (après astro build, avant pagefind)
Ce script injecte dans dist/**/index.html un <span id="oldId"></span> juste avant lélément portant id="newId".
## 4) Contrôles (incassables)
### A) Vérifier quon na pas dIDs dupliqués en HTML
Script : scripts/audit-dist.mjs
Robustesse :
ignore <script> et <style> (évite faux positifs)
exige un espace avant id= (évite data-id=)
Exécution :
npm run audit:dist
### B) Vérifier que les aliases sont vraiment présents dans dist
Script : scripts/verify-anchor-aliases-in-dist.mjs
Exécuté dans npm test
## 5) Mise à jour assistée (si besoin)
Pour générer/mettre à jour des aliases à partir des deltas dancres :
npm run test:anchors:update
## 6) ⚠️ Artefacts macOS (PaxHeader / ._ / DS_Store)
Quand on transfère une archive depuis macOS, on peut importer des dossiers/fichiers parasites :
PaxHeader/
._*
.DS_Store
Ces artefacts peuvent polluer le build (Astro croit voir un “vrai” contenu MDX).
➡️ Recommandation : .dockerignore strict :
# macOS / archives
.DS_Store
._*
**/._*
PaxHeader
**/PaxHeader
# Node
node_modules
dist
# (Optionnel) Avant build sur NAS : supprimer ces dossiers si présents.