Files
archicratie-edition/docs/ROADMAP.md
archicratia 60d88939b0
All checks were successful
CI / build-and-anchors (push) Successful in 1m25s
SMOKE / smoke (push) Successful in 11s
CI / build-and-anchors (pull_request) Successful in 1m20s
Seed from NAS prod snapshot 20260130-190531
2026-01-31 10:51:38 +00:00

8.0 KiB
Raw Permalink Blame History

ROADMAP — CI (Gitea Actions Synology) + Ancrages (aliases build-time)

But : permettre à un successeur de reprendre sans rien deviner. Ce document décrit :

  • létat stable actuel (baseline)
  • les invariants à ne pas casser
  • les prochaines étapes “mission principale” (ancrages primaires robustes + CI durable)
  • la méthode de debug rapide

0) État actuel (baseline VALIDÉE)

CI (Gitea Actions)

  • Job dans un container Node 22 (conforme engines)
  • Checkout sans actions GitHub, depuis workflow/event.json
  • Zéro apt-get dans le workflow
  • npm ci + build + tests anchors + validation schema aliases
  • Injection daliases au postbuild confirmée en logs

Runner (DS220+)

  • container.network: host dans /data/config.yaml du runner
  • NODE_OPTIONS=--dns-result-order=ipv4first passé aux containers de job
  • --add-host=gitea.archicratie.trans-hands.synology.me:192.168.1.20

Raison : le DNS du bridge Docker (127.0.0.11) est instable sur cette infra → EAI_AGAIN / ESERVFAIL (npm, debian).

Référence : docs/CI-BASELINE.md + docs/CI-WORKFLOW.md + docs/HANDOFF-SESSION.md.


1) Invariants (NE PAS “optimiser”)

Ces points sont des garde-fous. Si on les retire, on revient aux mêmes pannes.

  1. Runner :
  • garder container.network: host (tant que linfra DNS bridge nest pas corrigée)
  • garder -e NODE_OPTIONS=--dns-result-order=ipv4first
  1. Workflow :
  • ne pas réintroduire apt-get
  • ne pas dépendre de actions/checkout@...
  • garder un container Node 22 tant que package.json engines impose >=22 <23
  1. Ancrages :
  • le fichier canonique : src/anchors/anchor-aliases.json
  • injection build-time : scripts/inject-anchor-aliases.mjs
  • test anchors : scripts/check-anchors.mjs
  • validation schema aliases : scripts/check-anchor-aliases.mjs

2) Mission principale (raccrochage)

Objectif “métier” :

  • préserver les liens profonds (ancrages) malgré lédition (déplacements, insertions, corrections)
  • éviter les résolutions “par index” (fragiles)
  • rendre la migration dancrages déterministe, versionnée, testée

Traduction technique :

  • quand un newId remplace un oldId, on versionne oldId -> newId par page
  • au build, on injecte un alias DOM invisible portant lancien id avant lélément ciblé

3) Prochains jalons (ordre recommandé)

Jalons A — Verrouillage qualité (court terme, “béton”)

A1) CI : prouver linjection (pas seulement “build ok”)

  • ajouter un test qui parcourt src/anchors/anchor-aliases.json et vérifie dans dist/<route>/index.html :
    • présence de <span id="oldId" ...>
    • présence de lélément id="newId"
    • et idéalement : alias placé “juste avant” la cible (proximité)

A2) CI : interdire les IDs en double (risque SEO/DOM)

  • dans les pages dist, détecter les doublons dattribut id="..."

A3) CI : artefacts / logs actionnables

  • quand un test échoue : afficher route, oldId, newId, extrait HTML et ligne

Jalons B — Ergonomie éditeur (moyen terme)

B1) apply-ticket.mjs : renforcer le mode --alias

  • si un paragraphe est remplacé : écrire lalias automatiquement
  • si conflit : message clair “oldId déjà mappé / newId introuvable”

B2) check-anchors.mjs : suggestion daliases

  • lorsquil détecte “removed X / added Y” avec même préfixe p-8-...
  • générer une proposition, option --write-aliases (ou sortie patch)

Jalons C — Robustesse long terme (ops)

C1) Runner : réduire le risque “host network”

  • isoler le runner sur LAN (réseau dédié/pare-feu)
  • limiter les labels/queues aux repos nécessaires
  • documenter comment restaurer /data/config.yaml

C2) Versionner les décisions

  • tout changement CI/runner : documenté dans docs/ + commit (pas de “magic fix” non tracé)

4) Procédure standard (dev -> PR -> merge)

Ajouter/modifier du contenu

  1. modifier les sources (docx/import etc.)
  2. si des IDs de paragraphes changent :
    • appliquer scripts/apply-ticket.mjs --alias si possible
    • sinon éditer src/anchors/anchor-aliases.json (par route)

Vérifier en local

  • npm test
  • ou au minimum :
    • npm run build
    • vérifier injection : grep -n "para-alias" dist/<route>/index.html

PR & merge

  • une PR = un ticket logique
  • CI doit passer
  • merge seulement quand anchors + aliases sont cohérents

5) Debug express (quand ça casse)

CI échoue “DNS / npm”

Symptômes typiques :

  • EAI_AGAIN, ESERVFAIL, Temporary failure resolving Actions :
  1. vérifier runner config : /data/config.yaml contient bien network: host
  2. vérifier job container : logs montrent network="host"
  3. smoke test NAS :
    • docker run --rm --network host mcr.microsoft.com/devcontainers/javascript-node:22-bookworm bash -lc "npm ping --registry=https://registry.npmjs.org"

CI échoue “EBADENGINE”

  • Node pas 22 → corriger limage du job (Node 22)

CI échoue “MODULE_NOT_FOUND scripts/...”

  • fichier non commité
  • git status --porcelain puis git add/commit/push

Injection dalias absente

  • vérifier que postbuild appelle bien inject-anchor-aliases.mjs
  • vérifier que src/anchors/anchor-aliases.json respecte le schéma (par route)

6) Définition de “DONE” (quand on peut dire “mission accomplie”)

  1. CI stable sur 30+ runs consécutifs (push + PR + merge)
  2. Toute modification de paragraphes qui casse des anchors produit :
    • soit un alias automatique via tooling
    • soit un échec CI explicite (avec patch proposé)
  3. Aliases injectés testés (preuve dans dist) + pas de doublons dIDs
  4. Documentation à jour (baseline + décisions + procédures)

P2 — UX / Front “lecture outillée” (verrouillé)

  • Scroll unique dans le panneau gauche (TOC global + local).
  • Bandeau H1/H2/H3 aligné au reading + offsets dancres cohérents.
  • Boucle “Proposer” rétablie : modal 2 étapes (type + category) puis ouverture Gitea en nouvel onglet.
  • Bookmarks + reprise de lecture + citation copiable.
  • Procédure de diagnostic (terminal + dist + DevTools Firefox).

Dernière mise à jour : 2026-01-29


Réalisé (socle solide)

A) Ancrages stables (anti-casse)

  • Aliasing dancres à la build (déterministe) :
    • mapping versionné (ex: docs/anchor-aliases.json)
    • injection dans dist/**/index.html via scripts/inject-anchor-aliases.mjs
  • Audit dist : détection des IDs dupliqués (sans faux positifs JS/CSS) via scripts/audit-dist.mjs
  • Vérification “aliases réellement présents dans dist” via scripts/verify-anchor-aliases-in-dist.mjs

B) Qualité CI

  • Suite de tests npm test (build + audit + anchors + inline JS)

C) Production DS220+ (DSM 7.3) — Blue/Green

  • Build Astro en image Docker (Node Debian) + runtime Nginx statique
  • 2 slots :
    • web_blue → 127.0.0.1:8081
    • web_green → 127.0.0.1:8082
  • Reverse Proxy DSM :
    • bascule port 8081/8082 = bascule prod (rollback ~10s)
  • Variables PUBLIC_GITEA_* injectées au build → “Proposer” fonctionne end-to-end
  • Smoke test + healthcheck opérationnels

Docs :

  • DEPLOY_PROD_SYNOLOGY_DS220.md
  • OPS_COCKPIT.md

⏭️ Prochaines actions “futées” (à très forte valeur)

1) Automatiser le cycle blue/green (sans complexifier)

  • Script scripts/deploy-slot.sh green :
    • build --no-cache
    • up --force-recreate
    • smoke + health
    • imprime “OK pour bascule DSM vers 8082”
  • Script scripts/which-live.sh :
    • compare 8081/8082 avec le domaine public

2) Durcir lhygiène “transfert macOS → NAS”

  • .dockerignore contre PaxHeader/, ._*, .DS_Store
  • (optionnel) script scripts/clean-macos-artifacts.sh

3) Observabilité minimale

  • page “/healthz” (statique) ou check /pagefind/pagefind.js
  • journalisation Nginx : garder 23 jours, rotation simple (optionnel)

4) Sécurité reverse proxy

  • confirmer headers (HSTS si voulu, CSP si nécessaire)
  • sassurer que 8081/8082 restent local-only (127.0.0.1)

Fin.