No description
- Python 47.8%
- Shell 47.8%
- Dockerfile 1.5%
- Ruby 1.5%
- Nix 1.4%
G3 non mesuré avant le flip (mea culpa : supposé 'moteur constant = latence OK', faux). Toléré par Nicolas mais à optimiser (trimmer défauts 0.17 environment_probe/guidances/ coding_context qui gonflent le prefill). NEXT_TASK_ID 149->150. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .claude/skills | ||
| .planning/reports | ||
| atlas | ||
| backlog | ||
| docs | ||
| miniflux | ||
| nix | ||
| queue-staging | ||
| scripts | ||
| secrets | ||
| vault-templates | ||
| vps | ||
| .gitignore | ||
| .mcp.json | ||
| .sops.yaml | ||
| CLAUDE.md | ||
| COWORK-START-HERE.md | ||
| cron-desired.txt | ||
| README.md | ||
| watch-releases.txt | ||
infra/ — Infrastructure-as-Code Second Brain Nicolas
Repo source-of-truth de toute l'infra du second cerveau. Idempotent, déclaratif, rejouable depuis zéro en quelques commandes.
Dernière mise à jour : 2026-05-17 (post-Mission 3c)
Architecture en bref
atlas = Mac mini M4 Pro 24 GB user: exalti (oMLX — pure inférence LLM)
apollon = VPS Hostinger Paris user: nicolas (Hermes, CouchDB, livesync-cli, Caddy, Forgejo, Miniflux, vault source-of-truth)
artemis = MacBook user: nicolas (Claude Code, Obsidian, dev/devops)
echo = iPhone (Obsidian iOS, Telegram, WhatsApp)
⚠️ Convention SSH asymétrique : exalti@atlas, nicolas@apollon, nicolas@artemis.
- Tailnet Tailscale :
taildcde56.ts.net(Free plan, MagicDNS résoutatlas,apollon,artemis,echo). - Domaine public :
exalti.cloud(wildcard*.exalti.cloud→72.61.104.153chez Hostinger). - Services HTTPS publics :
vault.exalti.cloud(CouchDB),hermes.exalti.cloud(Hermes),forgejo.exalti.cloud,news.exalti.cloud(Miniflux).
Stack par machine
Atlas — Pure inférence LLM (post-Mission 1)
- oMLX servi via
eu.exalti.omlx.plist(launchd, KeepAlive auto-restart) - Modèles dans
~/models/, paged SSD cache~/.omlx/cache/ - Endpoint OpenAI-compatible :
http://atlas:8000/v1 - Modèle prod :
gemma-4-26b-a4b-it-4bit(verdict Round 7) - Healthcheck cron */5 min :
scripts/healthcheck-omlx.sh - Logs :
~/.omlx/logs/server.log+~/Library/Logs/omlx.{out,err}.log(rotation vianewsyslog.d) - Ollama complètement désinstallé (Mission 1 — +222 GB libérés)
Apollon — VPS infra full Docker
Stack docker-compose (vps/docker-compose.yml) :
| Service | Rôle |
|---|---|
caddy |
Reverse proxy + TLS automatique |
couchdb |
DB sync vault (utilisée par plugin Obsidian LiveSync + livesync-cli) |
hermes |
Agent IA Nous Research, accède au vault via bind-mount /vault |
livesync-cli |
Container daemon qui propage vault filesystem ↔ CouchDB (Mission 3c) |
forgejo |
Forge Git self-hosted |
miniflux |
RSS reader self-hosted |
Vault source-of-truth : /home/nicolas/vault/ (66 .md, autocommit cron */30 min).
Secrets prod (vps/.env) : COUCHDB_PASSWORD. NE JAMAIS commit (ignoré par .gitignore).
Artemis — Workstation Nicolas
- Obsidian + plugin Self-hosted LiveSync (sync via CouchDB)
- Claude Code (sessions interactives + missions structurées)
- Repo
~/projets/infra/iac(commits + push depuis ici uniquement, convention)
Echo — iPhone
- Obsidian iOS + plugin Self-hosted LiveSync
- Telegram, WhatsApp (futur intake pour Hermes — Mission 5)
Structure repo
iac/
├── CLAUDE.md ← onboarding agent
├── README.md ← ce fichier
├── .gitignore + .sops.yaml
├── atlas/
│ ├── omlx/ ← config oMLX prod (settings.json)
│ └── archived/ollama-pre-omlx/ ← Modelfiles historiques (Rounds 1-7)
├── vps/
│ ├── docker-compose.yml ← stack Apollon (6 services)
│ ├── .env.example ← template (jamais le vrai .env)
│ ├── bootstrap.sh + init-user.sh ← setup from zero
│ ├── caddy/Caddyfile
│ ├── couchdb/local.ini
│ ├── hermes/{config.yaml, skills/}
│ └── systemd/archived/ ← legacy livesync-cli.service (avant Mission 3c)
├── nix/
│ ├── launchd/ ← plists macOS prod + archived/
│ └── newsyslog.d/ ← rotation logs
├── scripts/
│ ├── eval-model*.sh ← benchmark LLM (réutilisable rounds futurs)
│ ├── healthcheck-omlx.sh
│ ├── setup-couchdb.sh
│ ├── vault-autocommit-apollon.sh
│ ├── recovery/ ← 4 scripts disaster recovery idempotents
│ └── archived/ ← legacy + prompts de bench archivés
├── secrets/ ← chiffrés age+sops
└── docs/
├── runbook.md ← procédures opérationnelles globales
├── runbook-omlx.md ← oMLX prod
├── runbook-vault.md ← vault sync (livesync-cli + autocommit)
├── runbook-vault-rag.md ← RAG vault Hermes
├── local-llm-hermes-agent.md
├── apollon-from-zero.md
├── macs-setup.md
├── couchdb-setup.md
├── templates-frontmatter.md
├── post-round7-consolidation-report-2026-05-18.md
├── roadmap-2026-05-17.md
└── archived/ ← handovers exécutés, rapports, test-results
Workflows courants
Mettre à jour Apollon (Docker)
ssh nicolas@apollon
cd ~/iac && git pull
cd vps && docker compose pull && docker compose up -d
⚠️ Vérifier .env présent AVANT tout docker compose up qui touche couchdb (cf. piège incident Mission 3c).
Mettre à jour Atlas (oMLX)
ssh exalti@atlas
cd ~/projets/infra/iac && git pull
# Si binaire oMLX à mettre à jour :
brew upgrade jundot/omlx/omlx
launchctl unload ~/Library/LaunchAgents/eu.exalti.omlx.plist
launchctl load ~/Library/LaunchAgents/eu.exalti.omlx.plist
Disaster recovery
Voir scripts/recovery/ :
bootstrap-atlas.sh— remonter Atlas from zero (oMLX + plist + healthcheck + newsyslog)bootstrap-apollon.sh— remonter Apollon from zero (Docker + Tailscale + stack compose + secrets)restore-vault.sh— restaurer le vault depuis CouchDB (livesync-cli mirror) ou depuis Gitsanity-check-all.sh— vérifier l'état de tous les services prod (Atlas + Apollon)
Procédures détaillées : docs/runbook.md.
Rotation des secrets
sops secrets/infra.yaml.sops # décrypte pour édition
# modifier, sauver — sops réencrypte
git add secrets/infra.yaml.sops && git commit -m "rotate: <quelle clé>" && git push
Roadmap
Vision Now/Next/Later : docs/roadmap-2026-05-17.md.
État courant (2026-05-18)
| Milestone | État |
|---|---|
| M0 Fondations sécurité | ✅ TERMINÉ (2026-05-12) |
| M1 Vault Obsidian + LiveSync | ✅ TERMINÉ (2026-05-14) |
| M2 Hermes + Ollama puis oMLX | ✅ TERMINÉ (2026-05-17, Rounds 1-7) |
| Mission 1 Cleanup Ollama + oMLX prod-grade | ✅ TERMINÉ (+222 GB libérés) |
| Mission 2 RAG vault Hermes — solution zéro-custom | ✅ TERMINÉ |
| Mission 3 / 3b / 3c Vault source-of-truth Apollon + livesync-cli daemon Docker | ✅ TERMINÉ |
| Stress test v1 + v2 + Quick Wins | ✅ TERMINÉ — 3 bugs identifiés, 1 fixé (UTF-8 + TZ) |
| Fix UTF-8 + timezone Hermes | ✅ TERMINÉ (LANG=C.UTF-8 + TZ=Europe/Paris) |
| Mission 4 RAG CRM vault opérationnel (SCHEMA + skills + cron) | 🟡 PARTIEL — vault CRM en place, skills + 2 cron OK, MCP MS365 désactivé (context overflow 161K tokens) |
| Mission 4b MS365 via Graph API custom (script Python ~100 lignes, scopes restreints "draft only") | ⏳ À briefer — voir lettre du matin |
| Mission 5 Messaging Telegram/WhatsApp | ⏳ Backlog |
| Mission 6 Forgejo + GitOps post-receive hook | ⏳ Backlog — le "game changer" pour stopper le jardinage sync entre machines |
Documents de référence
- Architecture globale + conventions :
CLAUDE.md(onboarding agent) - Apollon from zero :
docs/apollon-from-zero.md - Macs setup (Atlas + Artemis) :
docs/macs-setup.md - CouchDB setup + pièges :
docs/couchdb-setup.md - Runbook général + DR :
docs/runbook.md - Runbook oMLX :
docs/runbook-omlx.md - Runbook vault sync :
docs/runbook-vault.md - Runbook RAG CRM vault :
docs/runbook-vault-rag.md - Templates vault :
docs/templates-frontmatter.md - Brief technique Hermes Agent :
docs/local-llm-hermes-agent.md - Roadmap courante :
docs/roadmap-2026-05-17.md(Now/Next/Later/Maybe) - Archives :
docs/archived/(handovers exécutés, rapports, test-results, synthèses)