# HANDOFF — Bilan synthèse (passation)

## Mission
Rendre la CI Gitea Actions fiable (Synology) et sécuriser les ancrages de paragraphes :
- mapping oldId -> newId versionné
- injection build-time dans dist pour préserver les liens profonds

## Causes racines identifiées
1) DNS instable dans les conteneurs de job via bridge Docker (127.0.0.11) sur cette infra
2) Checkout GitHub externe impossible/indésirable + variables GITEA_* parfois absentes
3) engines Node imposent >=22 <23 => EBADENGINE si Node 20

## Résolution validée (baseline)
- Runner : container.network = host
- Job : image Node 22
- Checkout : via workflow/event.json (pas actions/checkout)
- Workflow : pas de apt-get
- Anchors :
  - src/anchors/anchor-aliases.json (par route)
  - scripts/inject-anchor-aliases.mjs injecte <span id="oldId"> avant l’élément id="newId"
  - scripts/check-anchor-aliases.mjs valide le schéma en CI

## État actuel
- CI passe (host net + Node 22 + checkout event.json + no apt)
- Injection d’aliases vérifiée localement dans dist/…/index.html

_________________________________________________

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

Ce document résume *tout le chemin* parcouru, avec les décisions qui évitent de “casser l’existant”.

---

## 1) Décision structurante : ancrages stables, déterministes

Problème initial :
- les IDs d’ancres peuvent varier (import, réécriture, reflow)
- un fallback “par index” (runtime) peut pointer un mauvais paragraphe si le texte change

Décision :
- aliasing d’ancres **à la build**
- mapping versionné
- injection dans `dist/**/index.html`

Implémentation :
- `docs/anchor-aliases.json` (ou équivalent)
- `scripts/inject-anchor-aliases.mjs` (executé en `postbuild`)

Résultat :
- liens profonds préservés
- comportement déterministe, auditable

---

## 2) Audit dist : rendre le contrôle “incassable”

Constat :
- une détection naïve des IDs peut ramasser des `id="..."` présents dans des strings JS/CSS

Action :
- durcissement `scripts/audit-dist.mjs` :
  - strip `<script>` + `<style>`
  - regex exigeant un espace avant `id=` (évite `data-id=`)

Résultat :
- plus de faux positifs
- signal de qualité fiable

---

## 3) Baseline tests (local + CI)

Consolidation :
- `npm test` enchaîne :
  - aliases OK
  - build
  - audit dist
  - vérif injection alias dans dist
  - check anchors (+ mode update)
  - check inline JS

Résultat :
- un “garde-fou” unique, simple, dur à casser

---

## 4) Déploiement production DS220+ (DSM 7.3) — accomplissement majeur

Objectif :
- sortir du “dev local Mac”
- publier une prod stable, rollback ultra rapide
- ne pas casser l’outil éditorial (tickets + labels + runner)

Décisions :
- build Astro dans image Docker (Node Debian “robuste”)
- runtime Nginx statique (léger)
- 2 slots blue/green (ports distincts)
- bascule par Reverse Proxy DSM (édition port)
- ports 8081/8082 bindés sur 127.0.0.1 (pas exposés WAN)

Spécificités DSM rencontrées et traitées :
- soucis réseau/DNS possibles pendant build → `build.network: host` + BuildKit
- transferts macOS pouvant injecter artefacts (`PaxHeader`, `._*`) → `.dockerignore` recommandé

Résultat :
- le site répond en HTTPS sur `archicratie.trans-hands.synology.me`
- Pagefind OK
- Proposer OK (création ticket + redirection Gitea)
- exécuteur (labels) OK

---

## 5) Gitea : diagnostic 404 “Proposer”

Cause typique :
- mauvais couple `OWNER/REPO` (casse sensible)

Action :
- vérification via API Gitea
- correction `.env` (ex : OWNER=Archicratia, REPO=archicratie-edition)
- rebuild image pour injecter les bonnes valeurs

Résultat :
- Proposer fonctionne end-to-end

---

## 6) Où sont les procédures

- Setup prod DSM : `DEPLOY_PROD_SYNOLOGY_DS220.md`
- Cockpit opérateur + rollback + dépannage : `OPS_COCKPIT.md`
- Anchors policy : `anchors.md`
- Baseline CI : `CI-BASELINE.md`