{
  "markdown": "# l0g.fr\n\nJournal statique (Astro 7 + Tailwind v4), édité en Markdown/MDX, versionné sur\nGitHub, déployé en pull-based sur un serveur Debian/Apache qui ne sert que du\nHTML. Infographies locales, recherche Pagefind, RSS, sitemap, aucun tracker.\n\n> Pour publier (articles, pages avec graphes, colonne de droite), voir le guide\n> pas à pas : [`docs/GUIDE-CONTENU.md`](docs/GUIDE-CONTENU.md).\n\n## Jouer en local\n\n```bash\nnpm install\nnpm run dev          # http://localhost:4321\n```\n\nAperçu d'un build de production (nécessaire pour tester la recherche Pagefind) :\n\n```bash\nnpm run build        # astro build + indexation pagefind\nnpm run preview\n```\n\n## Surfaces publiques\n\nl0g publie aussi des surfaces lisibles par machine, utilisées par les agents IA\net par les dashboards :\n\n- `/agents.json` : manifeste de découverte pour agents.\n- `/openapi.json` : contrat OpenAPI 3.1 de l'API publique.\n- `/api/v1/risk-diff.json` : diff du risque sur 1, 7 et 30 jours\n  (signaux, sources, claims, modèles, articles et confiance).\n- `/api/v1/black-box.json` : frames point-in-time hashées pour rejouer\n  l'état public du risque sans reconstruction rétroactive.\n- `/api/v1/risk.json` : signaux de risque normalisés par instrument.\n- `/api/v1/debt-risk.json` : snapshot canonique Dette US repris de Debt Risk\n  Radar `latest.json`, avec provenance, buckets et couverture lorsque disponible.\n- `/api/v1/signals/history.*` : historique point-in-time pour backtests et\n  replay sans look-ahead bias.\n- `/api/v1/signals/{slug}/chart.svg` : graphique autonome 1200 × 630 d'une\n  série nommée, avec source et attribution CC BY 4.0 intégrées.\n- `/ressources-journalistes/` et `/en/press-resources/` : graphiques, exports,\n  code d'intégration, citations recommandées et limites de réutilisation.\n- `/api/mcp/compact` : façade MCP recommandée à six outils, avec découverte,\n  recherche, documents, preuves, research packs et `get_risk_state`, produit\n  principal pour l’état courant, le diff, l’historique et le replay.\n- `/api/mcp` : surface MCP complète en lecture seule, conservée pour compatibilité\n  et usages experts autour d'Agent Surface, Risk Diff, Black Box, claims, sources,\n  intégrité et changefeed.\n- `/api/v1/toolset-manifest.json` : versions et empreintes anti-dérive des contrats\n  d'outils MCP complet et compact.\n- `/api/v1/human-traffic.json` : GET HTML humains agrégés par jour, page et\n  domaine référent, plus une ventilation séparée MCP/API, previews, robots et\n  scans ; sans identifiant persistant et avec seuil k=5.\n- `/llms.txt` et `/llms-full.txt` : cartes textuelles pour agents et RAG.\n\nLes détails de calcul et les limites de modèle sont dans\n[`docs/MODELES-RISQUE.md`](docs/MODELES-RISQUE.md) et dans\n`/methodologie/`.\n\n## Outil interne de revue des claims\n\nL'UI de revue humaine des assertions (tooling d’admin) est volontairement\nisolée du site public et du MCP. Elle n'est pas exposée publiquement :\n\n- serveur local: `127.0.0.1:4317`\n- endpoint principal: `http://127.0.0.1:4317/`\n\nLancement :\n\n```bash\nnode scripts/review-claims.mjs\n```\n\nLe mode commit reste strictement en terminal :\n\n```bash\nnode scripts/review-claims.mjs --commit [--dry-run] [--push] --message \"...\" \n```\n\nDétails sécurité côté local :\n\n- seul localhost est accepté,\n- toutes les mutations API (`/api/review`, `/api/remove`) exigent JSON + token anti-CSRF propre à la session (`x-review-token`),\n- validation de payload (longueurs/champs),\n- anti-spam local par fenêtre de temps sur les routes de mutation,\n- commit Git en mode interactif terminal uniquement avec confirmation explicite `CONFIRMER`.\n\nLe MCP public et les endpoints de production ne sont pas affectés par ces options.\n\n### Dépannage rapide\n\nEn cas d’erreur dans l’UI de revue :\n\n1. **Requête rejetée avec `Token de sécurité manquant ou invalide`**\n   - Rafraîchis la page (`Cmd/Ctrl + R`) puis rejoue l’action.\n   - Si ça persiste, arrête puis relance le service :\n     - `Ctrl+C` dans le terminal qui a lancé `node scripts/review-claims.mjs`\n     - relance `node scripts/review-claims.mjs`\n   - Evite d’avoir plusieurs tabs de cette UI ouvertes.\n\n2. **Erreur `Method not allowed` / 405**\n   - Vérifie de ne pas appeler les endpoints de manière manuelle hors UI.\n   - Les routes mutantes attendent uniquement `POST` avec JSON.\n\n3. **Erreur `Content-Type invalide: application/json requis`**\n   - C’est normal si une requête n’envoie pas `content-type: application/json`.\n   - L’UI interne envoie bien ce header.\n\n4. **Erreur de débit (`Trop de requêtes`)**\n   - Attends quelques secondes puis reteste ; la limite locale est 30 requêtes / minute.\n   - Cela protège le endpoint admin local contre le spam.\n\n5. **Erreur `Requête trop volumineuse` / champs trop longs**\n   - Réduis la taille du payload dans le formulaire (note, preuve, localisateur).\n   - Le message de commit reste inchangé : il s’agit d’un guard local par design.\n\n### Checklist opérationnelle de maintenance\n\n- Avant de modifier ce flux local :\n  - vérifier qu’aucune donnée sensible de production n’est présente sur le poste (workflow git local propre),\n  - arrêter le serveur review existant (`Ctrl+C`) avant de relancer la commande,\n  - démarrer avec `node scripts/review-claims.mjs`,\n  - valider une review test puis vérifier la sortie JSON du serveur (`/api/state`).\n- En cas de hardening ou de changement de format de review :\n  - relancer un `git status --short`,\n  - exécuter `node scripts/review-claims.mjs --commit --dry-run --message \"...\"`,\n  - vérifier le diff affiché n’éditera que `src/config/claim-reviews.json`,\n  - exécuter le `commit --dry-run` réel avec `CONFIRMER` uniquement si le diff est conforme.\n- Après mise à jour :\n  - redémarrer le serveur review local,\n  - conserver la trace des événements sécurité récents si nécessaire :\n    - `curl -s http://127.0.0.1:4317/api/security-stats`\n\n## Modèles de risque\n\nDeux corrections de modèle sont maintenant reflétées dans les surfaces l0g :\n\n- **Debt Risk Radar** : les projections CBO restent isolées comme vulnérabilité\n  structurelle. Le stress courant exclut CBO et impute les familles courantes\n  absentes à `50`, au lieu de renormaliser tout le score sur les seules sources\n  disponibles. Le prochain snapshot généré depuis `latest.json` expose\n  `score.coverage`.\n- **US Macro Dashboard** : le moteur ne retient plus mécaniquement le signal le\n  plus élevé entre z-score, drift et momentum. Il combine les composantes par\n  moyenne pondérée et pénalise les séries qui alertent trop souvent hors fenêtre\n  de récession NBER.\n\nAprès modification d'un moteur amont, régénérer les artefacts l0g avec\n`npm run risk:update`, puis `npm run test:risk-snapshot`,\n`npm run test:agent-surface` et `npm run build`.\n\n## Écrire un article\n\nCréer un fichier dans `src/content/posts/`, en `.md` (texte) ou `.mdx` (texte +\ncomposants). Frontmatter :\n\n```yaml\n---\ntitle: \"Titre de l'article\"\ndescription: \"Résumé court (liste + SEO + OG).\"\npubDate: 2026-06-08\ntags: [\"macro\", \"crypto\"]\ndraft: false        # true = non publié\n---\n```\n\nL'URL est dérivée du nom de fichier : `mon-article.md` → `/posts/mon-article/`.\n\n## Ajouter une infographie\n\nLes visuels publiés doivent être locaux : SVG inline dans un fichier `.mdx`,\ncomposant Astro interne ou fichier placé dans `public/infographies/`.\n\n```markdown\n![Description accessible du graphique](/infographies/mon-graphique.svg)\n```\n\nLes scripts, iframes, images et polices chargés depuis un domaine tiers sont\ninterdits. Le build de sécurité contrôle cette promesse.\n\nToute balise `<img>` doit déclarer ses dimensions intrinsèques `width` et\n`height`, ainsi que `loading=\"lazy\"` et `decoding=\"async\"`. L'audit de\nperformance bloque une régression susceptible de provoquer du CLS.\n\n## Déploiement (vue d'ensemble)\n\n### Politique CI frugale\n\n- Aucun workflow GitHub Actions n'est planifié par cron.\n- Le build attesté s'exécute sur un changement de `main` qui affecte le site,\n  ou à la demande. Les changements limités aux documents internes et aux\n  workflows sans effet sur le site ne republient pas `built`.\n- CodeQL conserve la suite `security-extended` sur les changements de code et\n  les pull requests, avec annulation des analyses devenues obsolètes. Les\n  changements purement éditoriaux ou statiques sont exclus.\n- Une modification de la chaîne risque valide automatiquement ses contrats\n  locaux. Le contrôle de bout en bout de la production s'exécute ensuite à la\n  demande, après activation de la révision serveur : un push ne peut donc plus\n  être déclaré en échec uniquement parce que la production sert encore la\n  révision précédente. Le timer serveur `l0g-risk.timer`, configuré toutes les\n  15 minutes, reste le mécanisme de production des agrégats.\n- `npm run test:ci-policy` bloque la réintroduction silencieuse d'un cron et\n  vérifie les principaux garde-fous de coût et de sécurité.\n\n### Migration attestée terminée et vérifiée le 21 juillet 2026\n\n- Le workflow CI publie dans `built` uniquement une enveloppe de release\n  composée de l'archive statique, du SHA-256, du bundle Sigstore et des\n  coordonnées du commit source. Ces coordonnées sont incluses dans\n  l'archive attestée et dupliquées à la racine de `built`; le déployeur exige\n  leur égalité octet par octet avant toute bascule.\n- Le serveur active exclusivement l'archive dont le checksum, l'attestation,\n  le workflow signataire, la ref et le commit source ont été vérifiés.\n- L'ancien arbre statique de compatibilité a été retiré après vérification en\n  production des marqueurs `.last_source_sha` et `.last_built_sha`.\n\nL'index des contrats, runbooks et versions maintenues se trouve dans\n[`docs/README.md`](docs/README.md).\n\n1. `git push` sur `main`.\n2. GitHub Actions construit `dist/`, crée une archive déterministe de toute la\n   sortie, puis l'atteste avec GitHub OIDC et Sigstore.\n3. La branche `built` contient uniquement l'archive, son SHA-256, le bundle\n   d'attestation et les coordonnées du commit source de `main`.\n4. Le timer systemd poll `built` toutes les 2 min.\n   Avant toute bascule, il exige\n   que le clone corresponde au HEAD distant de `built`, que le SHA source\n   corresponde au HEAD distant de `main`, et que `gh attestation verify`\n   confirme l'archive, le workflow signataire, la ref et le commit source.\n5. L'archive est contrôlée contre les traversées de chemin et les liens, extraite\n   dans une release isolée, puis le symlink servi par Apache est basculé\n   atomiquement.\n\nLe déploiement statique n'exécute aucune toolchain Node, ne build rien et\nn'ouvre aucun port entrant. Le serveur ne possède aucun token GitHub permanent.\n\n## Mise en place serveur (une fois)\n\n```bash\n# prérequis de vérification\ngit --version\ngh --version\ngh attestation verify --help >/dev/null\n\n# utilisateur dédié\nsudo useradd --system --create-home --shell /usr/sbin/nologin l0gdeploy\nsudo mkdir -p /var/www/html/l0g && sudo chown l0gdeploy:l0gdeploy /var/www/html/l0g\n\n# installation initiale des unités\nsudo install -m 0755 deploy/deploy.sh /usr/local/bin/l0g-deploy.sh\nsudo install -m 0644 deploy/l0g-deploy.service /etc/systemd/system/\nsudo install -m 0644 deploy/l0g-deploy.timer /etc/systemd/system/\nsudo systemctl daemon-reload\nsudo systemctl enable --now l0g-deploy.timer\nsudo systemctl start l0g-deploy.service\n\n# Apache\nsudo a2enmod ssl headers deflate expires rewrite auth_basic authn_file\nsudo apt-get install apache2-utils\nsudo htpasswd -cB /etc/apache2/l0g-stats.htpasswd bluetouff\nsudo chown root:www-data /etc/apache2/l0g-stats.htpasswd\nsudo chmod 0640 /etc/apache2/l0g-stats.htpasswd\n# Agrégat quotidien des GET HTML humains, à installer avant le vhost qui publie son JSON\nsudo deploy/install-human-traffic.sh\nsudo cp deploy/l0g.fr.apache.conf /etc/apache2/sites-available/\nsudo a2ensite l0g.fr.apache.conf\nsudo certbot --apache -d l0g.fr -d www.l0g.fr   # ou certonly puis reload\nsudo systemctl reload apache2\n```\n\nPour migrer un serveur qui possède déjà l'ancien timer, utiliser plutôt le\nscript transactionnel. Il sauvegarde le worker et les unités, vérifie le\npremier déploiement attesté et restaure automatiquement l'ancien worker, les\nunités, le symlink courant et les marqueurs si l'activation échoue :\n\n```bash\nsudo deploy/activate-worker.sh\n```\n\nSi la version Debian de `gh` ne fournit pas `attestation verify`, suivre le bloc\nd'installation depuis le dépôt officiel GitHub dans\n[`docs/MCP-RELEASE.md`](docs/MCP-RELEASE.md#migration-unique-de-zen). Tant que\nl'archive attestée ou l'outil de vérification manque, le script refuse la\nrelease et conserve le symlink courant.\n\nContrôles après le premier déploiement attesté :\n\n```bash\nsudo systemctl start l0g-deploy.service\nsudo systemctl status l0g-deploy.service l0g-deploy.timer --no-pager\nsudo journalctl -u l0g-deploy.service -n 100 --no-pager\ncat /var/www/html/l0g/.last_source_sha\ncat /var/www/html/l0g/.last_built_sha\nreadlink -f /var/www/html/l0g/current\n```\n\n## Mises à jour sans y penser\n\n- **Dépendances** : activer Renovate sur le dépôt. `renovate.json` fusionne\n  automatiquement patch/minor quand la CI est verte. Le preset\n  `helpers:pinGitHubActionDigests` conserve toutes les Actions sur des SHA\n  immuables et ouvre les mises à jour de digest. Les majeures restent en PR\n  manuelle. Un build cassé ou une provenance incohérente n'atteint jamais la\n  prod : la release courante continue de servir.\n- **OS / Apache** : `unattended-upgrades` côté Debian.\n\n## Sécurité, en bref\n\n- Sortie 100% statique, pas de runtime, pas de base de données.\n- GitHub ne détient aucune clé d'accès au serveur ; le serveur ne fait que du\n  HTTPS sortant.\n- La branche `built` n'est pas une autorité seule : son archive doit être\n  attestée par `.github/workflows/build.yml` et provenir du HEAD courant de\n  `main` au moment de l'activation. Cette vérification est le contrat du nouveau\n  déployeur ; l'état transitoire du serveur est documenté plus haut.\n- CSP stricte (voir `deploy/l0g.fr.apache.conf`), HSTS, en-têtes durcis.\n- Unité de déploiement systemd sandboxée.\n\n## Licences et citation\n\n- code, schémas machine, scripts, tests, workflows et déploiement : **MIT** ;\n- textes, données et artefacts éditoriaux : **CC BY 4.0** ;\n- métadonnées de citation : [`CITATION.cff`](CITATION.cff) ;\n- release stable du protocole :\n  [`releases/l0g-editorial-protocol-1.0.0/`](releases/l0g-editorial-protocol-1.0.0/).\n\nLe fichier [`LICENSE`](LICENSE) définit précisément la portée et renvoie aux\ndeux textes juridiques complets dans `LICENSES/`.\n\n## Ajouter une UI d'édition plus tard (optionnel)\n\nLe site est en édition « git-pur » par choix de sécurité. Pour ajouter une UI\ntype CMS sans base de données, le plus propre avec Astro est **Keystatic**\n(git-based, schémas TypeScript). Cela réintroduit toutefois une route `/admin`\net un flux OAuth GitHub à autoriser dans la CSP — à peser contre le modèle\n« zéro runtime » actuel.\n",
  "bytes": 14818,
  "sha": "82da56859cf35dc9d0f717c8e8429faa63d0f5b3863e8d0cc5d8e0e6cbf27071",
  "repo_slug": "bluetouff/l0g",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_bluetouff_l0g_81c8db40/readme"
}