# START-HERE — Archicratie / Édition Web (v3)
> Onboarding + exploitation “nickel chrome” (DEV → Gitea → CI → Release → Blue/Green → Edge/SSO → localhost auto-sync)

## 0) TL;DR (la règle d’or)

- **Gitea = source canonique**.
- **`main` est protégée** : toute modification passe par **branche → PR → CI → merge**.
- **Le NAS n’est pas la source** : si un hotfix est fait sur NAS, il doit être **backporté immédiatement** via PR.
- **Le site est statique Astro** : la prod sert du HTML via nginx ; l’accès est contrôlé au niveau reverse-proxy (Traefik + Authelia).
- **Le localhost automatique n’est pas le repo de dev** : il tourne depuis un **worktree dédié**, synchronisé sur `origin/main`.

---

## 1) Architecture mentale (ultra simple)

- **DEV canonique (Mac Studio)** : édition, dev, tests, commits, pushes
- **Gitea** : dépôt canonique, PR, CI, workflows éditoriaux
- **NAS (DS220+)** : déploiement blue/green
  - `web_blue` → staging upstream → `127.0.0.1:8081`
  - `web_green` → live upstream → `127.0.0.1:8082`
- **Edge (Traefik)** : routage des hosts
  - `staging.archicratie...` → 8081
  - `archicratie...` → 8082
  - **Authelia** devant, via middleware `chain-auth@file`
- **Localhost auto-sync**
  - un **repo canonique de développement**
  - un **worktree localhost miroir de `origin/main`**
  - un **agent de sync**
  - un **agent Astro**

---

## 2) Répertoires & conventions (repo)

### 2.1 Contenu canon (édition)

- `src/content/**` : contenu MD / MDX canon
- `src/pages/**` : routes Astro
- `src/components/**` : composants UI
- `src/layouts/**` : layouts
- `src/styles/**` : CSS global

### 2.2 Annotations (pré-Édition “tickets”)

- `src/annotations/<workKey>/<slug>.yml`
- Exemple :
  `src/annotations/archicrat-ia/prologue.yml`

Objectif :
stocker “Références / Médias / Commentaires” par page et par paragraphe (`p-...`).

### 2.3 Scripts (tooling / build)

- `scripts/inject-anchor-aliases.mjs` : injection aliases dans `dist`
- `scripts/dedupe-ids-dist.mjs` : retrait IDs dupliqués
- `scripts/build-para-index.mjs` : index paragraphes
- `scripts/build-annotations-index.mjs` : index annotations
- `scripts/check-anchors.mjs` : contrat stabilité d’ancres
- `scripts/check-annotations*.mjs` : sanity YAML + médias

> Important : ces scripts ne sont pas accessoires.  
> Ils font partie du contrat de stabilité éditoriale.

---

## 3) Les trois espaces à ne jamais confondre

### 3.1 Repo canonique de développement

```text
/Volumes/FunIA/dev/archicratie-edition/site
```

Usage :

- développement normal
- branches de travail
- nouvelles fonctionnalités
- corrections manuelles
- commits
- pushes
- PR

### 3.2 Worktree localhost miroir de `main`

```text
/Users/s-funia/ops-local/archicratie/localhost-worktree
```

Branche attendue :

```text
localhost-sync
```

Usage :

- exécuter le localhost automatique
- refléter `origin/main`
- ne jamais servir d’espace de développement

### 3.3 Ops local hors repo

```text
/Users/s-funia/ops-local/archicratie
```

Usage :

- scripts d’exploitation
- état
- logs
- automatisation `launchd`

---

## 4) Pourquoi cette séparation existe

Il ne faut pas utiliser le repo canonique de développement comme serveur localhost permanent.

Sinon on mélange :

- travail en cours
- commits non poussés
- essais temporaires
- état réellement publié sur `main`

Le résultat devient ambigu.

La séparation retenue est donc :

- **repo canonique** = espace de développement
- **worktree localhost** = miroir exécutable de `origin/main`
- **ops local** = scripts et automatisation

C’est cette séparation qui rend le système lisible, robuste et opérable.

---

## 5) Workflow Git “pro” (main protégée)

### 5.1 Cycle standard (toute modif)

```bash
git checkout main
git pull --ff-only

BR="chore/xxx-$(date +%Y%m%d)"
git checkout -b "$BR"

# dev…
npm i
npm run build
npm run test:anchors

git add -A
git commit -m "xxx: description claire"
git push -u origin "$BR"
```

### 5.2 PR vers `main`

- ouvrir une PR dans Gitea
- attendre une CI verte
- merger
- laisser les workflows faire le reste

### 5.3 Cas spécial : hotfix prod (NAS)

On peut faire un hotfix d’urgence côté NAS si nécessaire.

Mais l’état final doit toujours revenir dans Gitea :

- branche
- PR
- CI
- merge

---

## 6) Déploiement (NAS) — principe

### 6.1 Release pack

On génère un pack reproductible, puis on déploie.

### 6.2 Blue/Green

- `web_blue` = staging (`8081`)
- `web_green` = live (`8082`)

Le reverse-proxy choisit l’upstream selon le host demandé.

---

## 7) Happy path complet

### 7.1 DEV (Mac)

```bash
git checkout main && git pull --ff-only
git checkout -b chore/my-change-$(date +%Y%m%d)

npm i
rm -rf .astro node_modules/.vite dist
npm run build
npm run test:anchors
npm run dev
```

### 7.2 Push + PR

```bash
git add -A
git commit -m "chore: my change"
git push -u origin chore/my-change-YYYYMMDD
```

Puis ouvrir la PR dans Gitea.

### 7.3 Déploiement NAS

Voir :

```text
docs/runbooks/DEPLOY-BLUE-GREEN.md
```

---

## 8) Localhost auto-sync — ce qu’il faut retenir

Le localhost automatique sert à voir **la vérité de `main`**, pas à développer du neuf.

### 8.1 Scripts principaux

#### Script de sync

```text
~/ops-local/archicratie/auto-sync-localhost.sh
```

Rôle :

- fetch `origin/main`
- réaligner le worktree localhost
- lancer `npm ci` si besoin
- redéclencher l’agent Astro si nécessaire

#### Script Astro

```text
~/ops-local/archicratie/run-astro-localhost.sh
```

Rôle :

- lancer `astro dev`
- depuis le bon worktree
- avec le bon runtime Node
- sur `127.0.0.1:4321`

> Oui : ce script est nécessaire.  
> Il isole proprement le lancement du serveur Astro dans un contexte `launchd` stable.

### 8.2 LaunchAgents

#### Agent sync

```text
~/Library/LaunchAgents/me.archicratie.localhost-sync.plist
```

#### Agent Astro

```text
~/Library/LaunchAgents/me.archicratie.localhost-astro.plist
```

### 8.3 Document de référence

Pour tout le détail d’exploitation du localhost automatique, lire :

```text
docs/OPS-LOCALHOST-AUTO-SYNC.md
```

---

## 9) Règle d’or : il y a deux usages locaux distincts

### 9.1 Voir ce qui est réellement sur `main`

Utiliser :

```text
http://127.0.0.1:4321
```

Ce localhost doit être considéré comme :

**un miroir local exécutable de `origin/main`**

### 9.2 Développer / tester une nouvelle fonctionnalité

Utiliser le repo canonique :

```bash
cd /Volumes/FunIA/dev/archicratie-edition/site
npm run dev
```

Donc :

- **localhost auto-sync** = vérité de `main`
- **localhost de dev manuel** = expérimentation en cours

Il ne faut pas les confondre.

---

## 10) Ce qu’il ne faut pas faire

### 10.1 Ne pas développer dans le worktree localhost

Le worktree localhost est piloté automatiquement.

Il peut être :

- réaligné
- nettoyé
- redémarré

Donc :

- pas de commits dedans
- pas de dev feature dedans
- pas d’expérimentation de fond dedans

### 10.2 Ne pas utiliser le repo canonique comme miroir auto-sync

Sinon on mélange :

- espace de dev
- état publié
- serveur local permanent

### 10.3 Ne pas remettre les scripts ops sur un volume externe

Les scripts d’ops doivent rester sous `HOME`.

Le fait de les mettre sous `/Volumes/...` a déjà provoqué des erreurs du type :

```text
Operation not permitted
```

### 10.4 Ne pas supprimer `run-astro-localhost.sh`

Ce script fait partie de l’architecture actuelle.
Le supprimer reviendrait à réintroduire le flou entre sync Git et exécution d’Astro.

---

## 11) Commandes de contrôle essentielles

### 11.1 État global

```bash
~/ops-local/archicratie/doctor-localhost.sh
```

### 11.2 État Git

```bash
git -C ~/ops-local/archicratie/localhost-worktree rev-parse HEAD
git -C /Volumes/FunIA/dev/archicratie-edition/site ls-remote origin refs/heads/main
git -C ~/ops-local/archicratie/localhost-worktree branch --show-current
```

### 11.3 État LaunchAgents

```bash
launchctl print "gui/$(id -u)/me.archicratie.localhost-sync" | sed -n '1,160p'
launchctl print "gui/$(id -u)/me.archicratie.localhost-astro" | sed -n '1,160p'
```

### 11.4 État logs

```bash
tail -n 120 ~/ops-local/archicratie/logs/auto-sync-localhost.log
tail -n 120 ~/ops-local/archicratie/logs/astro-localhost.log
tail -n 80 ~/Library/Logs/archicratie-localhost-sync.err.log
tail -n 80 ~/Library/Logs/archicratie-localhost-astro.err.log
```

### 11.5 État serveur

```bash
lsof -nP -iTCP:4321 -sTCP:LISTEN
PID="$(lsof -tiTCP:4321 -sTCP:LISTEN | head -n 1)"
ps -p "$PID" -o pid=,command=
lsof -a -p "$PID" -d cwd
```

### 11.6 Vérification contenu

```bash
curl -s http://127.0.0.1:4321/archicrat-ia/prologue/ | grep -n "taxe Zucman"
```

---

## 12) Problèmes classiques + diagnostic

### 12.1 “Le staging ne ressemble pas au local”

Comparer les upstream directs :

```bash
curl -sS http://127.0.0.1:8081/ | head -n 2
curl -sS http://127.0.0.1:8082/ | head -n 2
```

Vérifier le routeur edge :

```bash
curl -sSI -H 'Host: staging.archicratie.trans-hands.synology.me' http://127.0.0.1:18080/ \
 | grep -iE 'HTTP/|location:|x-archi-router'
```

Voir :

```text
docs/runbooks/EDGE-TRAEFIK.md
```

### 12.2 Canonical incorrect

Cause probable : `PUBLIC_SITE` mal injecté au build.

Test :

```bash
curl -sS http://127.0.0.1:8082/ | grep -oE 'rel="canonical" href="[^"]+"' | head -1
```

Voir :

```text
docs/runbooks/ENV-PUBLIC_SITE.md
```

### 12.3 Contrat anchors en échec après migration d’URL

Procédure safe :

```bash
cp -a tests/anchors-baseline.json /tmp/anchors-baseline.json.bak.$(date +%F-%H%M%S)

node - <<'NODE'
import fs from 'fs';
const p='tests/anchors-baseline.json';
const j=JSON.parse(fs.readFileSync(p,'utf8'));
const out={};
for (const [k,v] of Object.entries(j)) {
  const nk = k.replace(/^archicratie\/archicrat-ia\//, 'archicrat-ia/');
  out[nk]=v;
}
fs.writeFileSync(p, JSON.stringify(out,null,2)+'\n');
console.log('updated keys:', Object.keys(j).length, '->', Object.keys(out).length);
NODE

npm run test:anchors
```

### 12.4 “Le localhost auto-sync ne montre pas les dernières modifs”

Commande réflexe :

```bash
~/ops-local/archicratie/doctor-localhost.sh
```

Puis :

```bash
git -C ~/ops-local/archicratie/localhost-worktree rev-parse HEAD
git -C /Volumes/FunIA/dev/archicratie-edition/site ls-remote origin refs/heads/main
```

Si les SHA diffèrent :
- le sync n’a pas tourné
- ou l’agent sync a un problème

### 12.5 “Le SHA est bon mais le contenu web est faux”

Vérifier quel Astro écoute réellement :

```bash
lsof -nP -iTCP:4321 -sTCP:LISTEN
PID="$(lsof -tiTCP:4321 -sTCP:LISTEN | head -n 1)"
ps -p "$PID" -o pid=,command=
lsof -a -p "$PID" -d cwd
```

Attendu :
- commande contenant `astro dev`
- cwd = `~/ops-local/archicratie/localhost-worktree`

### 12.6 Erreur `EBADENGINE`

Cause probable :
- Node 23 utilisé au lieu de Node 22

Résolution :
- forcer `node@22` dans les scripts et les LaunchAgents

### 12.7 Erreur `Operation not permitted`

Cause probable :
- scripts d’ops placés sous `/Volumes/...`

Résolution :
- garder les scripts sous :

```text
~/ops-local/archicratie
```

### 12.8 Erreur `EPERM` sur `astro.mjs`

Cause probable :
- ancien worktree sur volume externe
- ancien chemin résiduel
- Astro lancé depuis un mauvais emplacement

Résolution :
- worktree localhost sous :

```text
~/ops-local/archicratie/localhost-worktree
```

- scripts cohérents avec ce chemin
- réinstallation propre via :

```bash
~/ops-local/archicratie/install-localhost-sync.sh
```

---

## 13) Redémarrage machine

Après reboot, le comportement attendu est :

1. le LaunchAgent sync se recharge
2. le LaunchAgent Astro se recharge
3. le worktree localhost est réaligné
4. Astro redémarre sur `127.0.0.1:4321`

### Vérification rapide après reboot

```bash
~/ops-local/archicratie/doctor-localhost.sh
```

Si nécessaire :

```bash
~/ops-local/archicratie/install-localhost-sync.sh
```

---

## 14) Procédure de secours manuelle

### Forcer un sync

```bash
~/ops-local/archicratie/auto-sync-localhost.sh
```

### Réinstaller proprement le dispositif local

```bash
~/ops-local/archicratie/install-localhost-sync.sh
```

### Diagnostic complet

```bash
~/ops-local/archicratie/doctor-localhost.sh
```

---

## 15) Décision d’exploitation finale

La politique retenue est la suivante :

- **repo canonique** = espace de développement
- **worktree localhost** = miroir automatique de `main`
- **ops sous HOME** = scripts, logs, automation
- **LaunchAgent sync** = réalignement Git
- **LaunchAgent Astro** = exécution stable du serveur local
- **Astro local** = lancé uniquement depuis le worktree localhost

Cette séparation rend le dispositif plus :

- lisible
- robuste
- opérable
- antifragile

---

## 16) Résumé opératoire

### Pour voir la vérité de `main`

Ouvrir :

```text
http://127.0.0.1:4321
```

Le serveur doit provenir de :

```text
/Users/s-funia/ops-local/archicratie/localhost-worktree
```

### Pour développer

Travailler dans :

```text
/Volumes/FunIA/dev/archicratie-edition/site
```

avec les commandes habituelles.

### Pour réparer vite

```bash
~/ops-local/archicratie/doctor-localhost.sh
~/ops-local/archicratie/auto-sync-localhost.sh
```

---

## 17) Mémoire courte

Si un jour plus rien n’est clair, repartir de ces commandes :

```bash
~/ops-local/archicratie/doctor-localhost.sh
git -C ~/ops-local/archicratie/localhost-worktree rev-parse HEAD
git -C /Volumes/FunIA/dev/archicratie-edition/site ls-remote origin refs/heads/main
lsof -nP -iTCP:4321 -sTCP:LISTEN
```

Puis lire :

```bash
tail -n 120 ~/ops-local/archicratie/logs/auto-sync-localhost.log
tail -n 120 ~/ops-local/archicratie/logs/astro-localhost.log
```

---

## 18) Statut actuel visé

Quand tout fonctionne correctement :

- le worktree localhost pointe sur le même SHA que `origin/main`
- `astro dev` écoute sur `127.0.0.1:4321`
- son cwd est `~/ops-local/archicratie/localhost-worktree`
- le contenu servi correspond au contenu mergé sur `main`

C’est l’état de référence à préserver.