feat: publish CodexPi contest snapshot
Some checks are pending
Qualité / tests (push) Waiting to run
Some checks are pending
Qualité / tests (push) Waiting to run
This commit is contained in:
118
docs/SECURITY_AUDIT.md
Normal file
118
docs/SECURITY_AUDIT.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# Audit de sécurité CodexPi
|
||||
|
||||
Date de révision : 13 septembre 2026.
|
||||
|
||||
## Architecture réseau
|
||||
|
||||
```text
|
||||
Ordinateur du LAN ── HTTP :8765 ─────────┐
|
||||
▼
|
||||
Tailscale Serve :443 (Funnel interdit) ─► nginx Docker
|
||||
├── Django/Uvicorn :8001 (réseau Docker uniquement)
|
||||
└── FastAPI/Uvicorn :8000 (réseau Docker uniquement)
|
||||
```
|
||||
|
||||
Le binding Compose publie uniquement nginx sur `0.0.0.0:8765`; FastAPI et Django restent internes au réseau Docker. Le port est destiné au LAN de confiance et ne doit jamais être redirigé sur la box. Le projet ne crée aucune règle UPnP, DMZ, redirection de port ou Tailscale Funnel.
|
||||
|
||||
## Menaces et protections
|
||||
|
||||
| Menace | Protection |
|
||||
|---|---|
|
||||
| exposition Internet accidentelle | aucune redirection de box, Tailscale Serve privé, refus de Funnel |
|
||||
| interception d'identifiants | HTTPS via Tailscale recommandé ; accès HTTP limité au LAN de confiance ; cookies HttpOnly/SameSite Strict |
|
||||
| brute force | limite par IP, délai progressif, verrouillage temporaire, journal des refus |
|
||||
| détournement de session/CSRF | session Django côté serveur, jeton CSRF de session, contrôle Origin WebSocket |
|
||||
| traversal/symlink | chemins canonisés, UUID projet, racines autorisées et interdites |
|
||||
| injection de commandes | arguments structurés et validateurs stricts, aucune saisie dans un shell |
|
||||
| téléversement malveillant | PNG/JPEG/WebP vérifiés par signature, 10 Mo max, UUID serveur, stockage privé, lecture authentifiée |
|
||||
| action destructive | confirmation explicite, surface Git/Docker limitée, aucun prune global |
|
||||
| élévation de privilèges | conteneurs non-root, capabilités supprimées, no-new-privileges, aucun sudo Codex |
|
||||
| fuite de secrets | `.env`, bases, clés et logs ignorés par Git ; journaux sans credentials |
|
||||
| mode développement | `DEBUG=False`, aucun `--reload`, contrôles Django de déploiement |
|
||||
|
||||
Le socket Docker monté dans le conteneur API demeure une capacité privilégiée nécessaire aux commandes Docker. L'accès CodexPi et au tailnet doit donc être réservé à des utilisateurs de confiance ; `FULL ACCESS` doit rester exceptionnel.
|
||||
|
||||
## Authentification et journalisation
|
||||
|
||||
Django gère les comptes, les mots de passe Argon2 et les sessions en base. FastAPI valide ces mêmes sessions avant tout accès REST ou WebSocket. Les cookies sont `HttpOnly` et `SameSite=Strict`; l'attribut `Secure` est désactivé lorsque l'accès direct HTTP par IP est activé.
|
||||
|
||||
`data/security.log` enregistre : connexion réussie/refusée, IP source/Tailscale transmise par nginx, date, session créée/supprimée, refus WebSocket, changement de paramètres de sécurité et activation/désactivation de `FULL ACCESS`.
|
||||
|
||||
Le journal ne reçoit jamais : mots de passe, cookies, jetons CSRF, tokens Codex, credentials OpenAI ou contenu de `.env`.
|
||||
|
||||
Les photos jointes restent dans `data/uploads/`, hors Git. Elles ne sont jamais publiées par nginx comme répertoire statique : FastAPI contrôle la session avant chaque lecture. Les prompts en attente et leurs références d'images sont persistés en SQLite et traités un par un par un worker non-root.
|
||||
|
||||
## Ports CodexPi
|
||||
|
||||
| Port | Exposition | Usage |
|
||||
|---:|---|---|
|
||||
| 443 | interface Tailscale uniquement | HTTPS privé Tailscale Serve |
|
||||
| 8765 | réseau local | nginx, accès par IP et cible de Tailscale Serve |
|
||||
| 8000 | réseau Docker seulement | FastAPI/Uvicorn |
|
||||
| 8001 | réseau Docker seulement | Django/Uvicorn |
|
||||
|
||||
Les autres ports visibles par `ss -tulpn` appartiennent à l'hôte ou à d'autres applications et ne sont pas modifiés par CodexPi.
|
||||
|
||||
## Firewall et fail2ban
|
||||
|
||||
Si UFW est actif, autorisez éventuellement `8765/tcp` uniquement depuis le sous-réseau local de confiance. Ne publiez jamais `8000` ou `8001` et n'autorisez pas `8765` depuis Internet.
|
||||
|
||||
Une jail fail2ban optionnelle est fournie sous `deploy/fail2ban/`. Le verrouillage applicatif est déjà actif ; avant toute activation fail2ban, sauvegardez la configuration existante, exécutez `fail2ban-client -t` et testez le filtre avec `fail2ban-regex`.
|
||||
|
||||
## Procédure d'accès
|
||||
|
||||
Sur le Pi :
|
||||
|
||||
```bash
|
||||
cd /home/config/CodexPi
|
||||
./scripts/install.sh
|
||||
./scripts/create-admin.sh
|
||||
./scripts/tailscale-serve.sh --check
|
||||
./scripts/tailscale-serve.sh --apply
|
||||
```
|
||||
|
||||
Le script affiche l'adresse MagicDNS exacte, typiquement `https://codexpi.<tailnet>.ts.net`. Elle doit être ouverte uniquement depuis un appareil connecté au même tailnet. La page Django demande ensuite l'identifiant CodexPi.
|
||||
|
||||
Sur iPhone/iPad : installez Tailscale depuis l'App Store, acceptez le profil VPN, connectez-vous au même compte/tailnet, activez Tailscale, puis ouvrez l'adresse HTTPS affichée par le script dans Safari. Le site peut ensuite être ajouté à l'écran d'accueil comme PWA.
|
||||
|
||||
## Vérifier l'absence d'accès public
|
||||
|
||||
1. Sur le téléphone, coupez le Wi-Fi et désactivez Tailscale.
|
||||
2. Ouvrez l'adresse `https://codexpi.<tailnet>.ts.net` : elle doit être inaccessible.
|
||||
3. Ne testez pas un port interne en l'ouvrant sur la box ; utilisez un scanner externe sur l'IP publique et confirmez qu'aucun service `8765`, `8000` ou `8001` n'apparaît.
|
||||
4. Sur le Pi, exécutez `ss -tulpn` : CodexPi peut montrer `0.0.0.0:8765`, mais jamais `0.0.0.0:8000` ou `0.0.0.0:8001`.
|
||||
5. Réactivez Tailscale : la même adresse HTTPS doit fonctionner et demander la connexion Django.
|
||||
|
||||
## Révocation d'accès
|
||||
|
||||
- Révoquer toutes les sessions web : `./scripts/revoke-sessions.sh`, puis saisir `REVOKE`.
|
||||
- Retirer la publication privée : `tailscale serve --https=443 off` ; utilisez `tailscale serve reset` seulement si le Pi ne publie rien d'autre.
|
||||
- Déconnecter le Pi : `sudo tailscale down`.
|
||||
- Révoquer définitivement un appareil depuis la page Machines de l'administration Tailscale.
|
||||
- Changer le mot de passe Django avec `docker compose run --rm django-web python3 manage.py changepassword <utilisateur>`.
|
||||
|
||||
## Audit exécutable
|
||||
|
||||
```bash
|
||||
cd /home/config/CodexPi
|
||||
./scripts/security-audit.sh
|
||||
./scripts/check-secrets.sh --worktree
|
||||
./scripts/check-secrets.sh --history
|
||||
```
|
||||
|
||||
Les secrets applicatifs sont externes au code : `.env` et `data/` sont ignorés,
|
||||
les identifiants GitLab/Gitea et SSH sont chiffrés dans les données persistantes,
|
||||
les clés GitHub sont créées sous `data/github/`, et la session du Codex CLI reste
|
||||
dans le dossier `.codex` monté depuis l'hôte. Pour un gestionnaire de secrets,
|
||||
montez des fichiers en lecture seule et définissez `CODEXPI_SECRET_KEY_FILE` et
|
||||
`CODEXPI_DJANGO_SECRET_KEY_FILE`.
|
||||
|
||||
Le script vérifie en lecture seule les ports, Compose, Tailscale/Funnel, UFW, fail2ban, permissions, propriétaires, secrets Git, headers HTTP, refus anonyme, debug Django/FastAPI et contrôles de déploiement.
|
||||
|
||||
## Résultat de la revue du code
|
||||
|
||||
- **Architecture Compose : conforme** — seul nginx déclare `ports`, sur le port LAN 8765.
|
||||
- **Authentification/cookies/CSRF/WebSocket : conforme dans l'implémentation** — Django reste l'autorité de session et FastAPI la valide.
|
||||
- **Traversal/injection/actions destructrices : protections conservées** — validation de projet et commandes structurées.
|
||||
- **Secrets/debug : conforme dans le dépôt** — secrets ignorés, Django `DEBUG=False`, aucun reload.
|
||||
- **État réseau réel du Pi : à confirmer après démarrage** avec `./scripts/security-audit.sh`, car un partage SMB ne permet pas d'interroger `ss`, UFW, Tailscale ou les conteneurs en cours d'exécution.
|
||||
60
docs/application-audit.md
Normal file
60
docs/application-audit.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Audit fonctionnel des 17 applications
|
||||
|
||||
Audit réalisé le 28 octobre 2026 à partir des sources, des dépôts Git, des tables SQLite et des routes réellement présentes. Un test enregistré dans `project_test_runs` n'est pas considéré comme un test métier lorsque le dépôt applicatif ne contient aucun code.
|
||||
|
||||
| Projet | Frontend | Backend | Base de données | Fonctions réelles | Tests | Statut vérifié |
|
||||
|---|---|---|---|---|---|---|
|
||||
| PWA Factory | Éditeur responsive intégré, aperçu | API CRUD et export ZIP | SQLite CodexPi | Création, modèles dashboard/tâches/catalogue, couleurs, pages, composants, sauvegarde, réouverture, manifest, service worker, export autonome | 4 tests métier passent, dont démarrage HTTP du ZIP | `TESTING` jusqu'au déploiement de la route |
|
||||
| Pi Doctor | Module intégré et application React livrée sur `codexpi/pi-doctor-v0` (`a5dc22e`) | Ingestion, incidents, snapshots, plans protégés et collecteur hôte en lecture seule | SQLite CodexPi + SQLite applicative/collecteur | Collecte, anomalies, diagnostic expurgé, décisions persistantes et garde-fous réels ; service systemd non installé, Docker cible et liaison CodexPi réelle non validés | 38 pytest + 3 frontend + 4 Playwright, build et HTTP loopback validés | `TESTING` |
|
||||
| LoutreOS | Application React responsive livrée sur `codexpi/loutre-os-v0` (`2021e40`) | FastAPI et collecteur hôte non privilégié, instantanés validés, API protégée | SQLite locale persistante | CPU/RAM/température/disques réels du runtime, historique, alertes, inventaire et connecteurs dégradables ; NAS/Docker/Jellyfin réels non contactés | 56 pytest + 7 Vitest + 2 Playwright, build, HTTP et redémarrage SQLite validés | `TESTING` |
|
||||
| Codex Commander | Module intégré et application React/FastAPI non commitée dans son worktree | Profils, missions, worker et file Codex | SQLite CodexPi et SQLite applicative | Lancement Codex intégré réel ; application isolée à consolider avec la session CodexPi et la validation navigateur | Artefacts existants : 12 pytest et build réussi ; tests navigateur non concluants | `FUNCTIONAL_PARTIAL` |
|
||||
| Autonomous Dev Studio | Formulaire/module intégré | Planification et lancement Codex intégrés | SQLite CodexPi | Requête, plan, validation et session Codex réels ; aucune exécution utilisateur enregistrée, V0 complète non prouvée | Tests d'acceptation dédiés absents | `FUNCTIONAL_PARTIAL` |
|
||||
| LoutreFinance | Application React métier non commitée dans son worktree | Django avec authentification, API et export | SQLite locale persistante | Comptes, opérations, catégories, budgets, récurrences, graphiques et CSV sont présents ; ouverture CodexPi et nouvelle revue restent à faire | Artefacts existants : 17 tests Django, 2 parcours Chromium et build réussis | `TESTING` |
|
||||
| Smart Inventory | React/Vite sur branche isolée, fiche générique dans CodexPi | FastAPI sur branche `codexpi/smart-inventory-v0` | SQLite + pièces jointes | CRUD, emplacements, documents, recherche, QR anonyme, CSV et sauvegarde existent dans le worktree ; aucune route CodexPi ne l'ouvre encore | 23 tests backend passent, build frontend réussi | `FUNCTIONAL_PARTIAL` |
|
||||
| AutoCare | React/Vite sur branche isolée, fiche générique dans CodexPi | FastAPI sur branche `codexpi/auto-care-v0` | SQLite + documents | Véhicule, kilométrage, entretiens, dépenses, carburant, contrats et rappels sont codés ; non intégré à l'URL applicative CodexPi | 25 tests backend passent, build frontend réussi | `FUNCTIONAL_PARTIAL` |
|
||||
| NetworkGuardian | React/Vite sur branche isolée, fiche générique dans CodexPi | FastAPI sur branche `codexpi/network-guardian-v0` | SQLite | Inventaire, sondes ICMP autorisées, historiques et alertes sont codés ; non intégré et connectivité réelle non revalidée ici | 29 tests backend passent, build frontend réussi | `FUNCTIONAL_PARTIAL` |
|
||||
| Reverse Proxy Manager | Application React métier non commitée dans son worktree | FastAPI, parseur Apache et contrôles TLS | SQLite locale | Inventaire vhosts/domaines/ProxyPass, analyses et lecture seule existent ; accès QNAP réel et workflow d'application validée restent à configurer | Artefacts existants : 25 pytest, 6 parcours Chromium et build réussis | `TESTING` |
|
||||
| LoutreBrain | Application React métier non commitée dans son worktree | FastAPI, extraction, SQLite FTS5 et recherche | SQLite + index FTS5 | Import, indexation, recherche textuelle, questions/réponses sourcées et historique existent ; recherche sémantique et ouverture CodexPi restent à consolider | Artefacts existants : 18 pytest et build réussi ; navigateur à revalider | `TESTING` |
|
||||
| Knowledge Graph | React/Vite et graphe SVG sur branche isolée, fiche générique dans CodexPi | FastAPI sur branche `codexpi/knowledge-graph-v0` | SQLite | Nœuds, relations, import JSON, recherche, filtres et impact sont codés ; profils uniquement fictifs et aucune ouverture CodexPi | 13 tests backend passent, build frontend réussi | `FUNCTIONAL_PARTIAL` |
|
||||
| PrintPilot | React/Vite sur branche isolée, fiche générique dans CodexPi | FastAPI sur branche `codexpi/print-pilot-v0` | SQLite + fichiers | Imprimantes, filaments, modèles 3MF/STL, travaux, coût, stocks et historique sont codés ; connecteur matériel absent et non intégré | 37 tests backend passent, build frontend réussi | `FUNCTIONAL_PARTIAL` |
|
||||
| LoutreHome | React/Vite sur branche isolée, fiche générique dans CodexPi | FastAPI sur branche `codexpi/loutre-home-v0` | SQLite de démonstration | Inventaire, historiques, scènes simulées et alertes locales en lecture seule ; aucun appareil/HA/MQTT réel et non intégré | 14 tests backend passent, build frontend réussi | `FUNCTIONAL_PARTIAL` |
|
||||
| TripOrganizer | React/Vite sur branche isolée, fiche générique dans CodexPi | FastAPI sur branche `codexpi/trip-organizer-v0` | SQLite + copie hors ligne chiffrée | Voyages, étapes, réservations, dépenses, checklist et cache hors ligne sont codés ; documents/carte absents et non intégré | 17 tests backend passent, build frontend réussi | `FUNCTIONAL_PARTIAL` |
|
||||
| NASFLIX MediaHealth | Écrans NASFLIX existants, pas d'application dédiée complète | Audit Jellyfin/fichiers en lecture seule présent dans NASFLIX | Stockages NASFLIX existants | Détection partielle de manquants/doublons ; rapport dédié et historique d'analyses V0 non prouvés | Tests NASFLIX connexes, pas d'acceptation MediaHealth complète | `FUNCTIONAL_PARTIAL` |
|
||||
| NASFLIX AI Media Curator | Module Curator intégré à NASFLIX | FastAPI, connecteur Jellyfin et moteur de recommandations | SQLite par compte | Catalogue, recherche, préférences et recommandations réels ; couverture métier et parcours complet non prouvés | Aucun test Curator dédié trouvé | `FUNCTIONAL_PARTIAL` |
|
||||
|
||||
## Constats structurants
|
||||
|
||||
- Les 14 branches principales sous `/home/config/LoutreProjects` ne contenaient que `.git` et un commit d'initialisation. Huit worktrees Codex conservaient toutefois du code non fusionné : AutoCare, Knowledge Graph, LoutreHome, NetworkGuardian, PrintPilot, PWA Factory, Smart Inventory et TripOrganizer.
|
||||
- Une seconde inspection incluant les fichiers non suivis a retrouvé six livraisons supplémentaires dans les worktrees LoutreOS, LoutreFinance, LoutreBrain, Reverse Proxy Manager, Pi Doctor et Codex Commander. Leur absence de commit expliquait le faux diagnostic « dépôt vide ». Ces sources sont désormais préservées et placées dans la file de reprise, sans être déclarées `READY_V0` avant revalidation et intégration.
|
||||
- Six badges `READY_V0` étaient déclaratifs : PWA Factory, LoutreOS, Reverse Proxy Manager, LoutreHome, Knowledge Graph et TripOrganizer.
|
||||
- Les pages publiques générées par `AppStoreService.application_page` affichaient les fonctionnalités comme « planifiées » et les compteurs de tâches/tests ; elles ne constituaient pas les applications.
|
||||
- Les 102 exécutions enregistrées dans `project_test_runs` ne prouvent pas à elles seules une V0. Les huit suites backend des worktrees ont été relancées séparément : 174 tests réussis au total, ainsi que leurs huit builds frontend. Leur absence d'intégration et d'URL CodexPi empêche néanmoins `READY_V0`.
|
||||
- L'orchestrateur ne promeut plus un projet en `READY_V0` sur la seule présence d'une commande réussie. Une commande réussie place au maximum le projet en `TESTING`.
|
||||
|
||||
## Critère de promotion
|
||||
|
||||
`READY_V0` reste réservé à une vérification d'acceptation séparée couvrant l'interface, les opérations métier principales, la persistance, le lien frontend/backend, les erreurs, le démarrage, l'URL de prévisualisation et l'absence de boutons essentiels fictifs.
|
||||
|
||||
## Suivi d'exécution
|
||||
|
||||
Ce tableau ne contient aucun pourcentage. « File » désigne la tâche persistante CodexPi créée le 28 octobre 2026. LoutreOS (`2021e40`) et Pi Doctor (`a5dc22e`) ont terminé leur session ; Codex Commander est l'unique mission active, les suivantes restent sérialisées.
|
||||
|
||||
| Projet | Fonctionnalités prouvées | Tests prouvés ou conservés | Intégration | Statut | Prochaine action |
|
||||
|---|---|---|---|---|---|
|
||||
| LoutreOS | Collecteur hôte, métriques, historique SQLite, alertes, inventaire et connecteurs dégradables | 56 backend + 7 frontend + 2 navigateur ; build/HTTP/persistance validés | Branche applicative et prévisualisation loopback validées ; ouverture CodexPi à raccorder avant déploiement | `TESTING` | Valider les connecteurs réels en recette privée puis intégrer la route de lancement |
|
||||
| NetworkGuardian | Inventaire, sondes autorisées, historique, alertes | 29 backend + build relancés | Fiche seulement | `FUNCTIONAL_PARTIAL` | Reprendre la tâche en pause et publier une prévisualisation interne |
|
||||
| Reverse Proxy Manager | Parseur Apache, vhosts, ProxyPass, TLS en lecture seule | 25 backend + 6 navigateur conservés | Fiche seulement | `TESTING` | Revalider puis configurer le connecteur QNAP avec validation utilisateur |
|
||||
| Codex Commander | Profils, missions, file et sessions Codex | 12 backend + build conservés ; navigateur incomplet | Module intégré partiel | `FUNCTIONAL_PARTIAL` | Unifier l'application isolée et le module CodexPi |
|
||||
| Autonomous Dev Studio | Spécification, plan, approbation, création de projet et tâche | 10 tests intégrés relancés | Module intégré | `FUNCTIONAL_PARTIAL` | Exécuter un parcours complet jusqu'à la prévisualisation |
|
||||
| LoutreBrain | Import, extraction, FTS5, recherche et réponses sourcées | 18 backend + build conservés | Fiche seulement | `TESTING` | Revalider, ajouter l'indexation CodexPi et intégrer l'ouverture |
|
||||
| LoutreFinance | Comptes, opérations, budgets, récurrences, graphiques, CSV | 17 Django + 2 navigateur conservés | Fiche seulement | `TESTING` | Revalider la persistance puis intégrer l'URL CodexPi |
|
||||
| PrintPilot | Imprimantes, filaments, modèles, travaux, coûts et stocks | 37 backend + build relancés | Fiche seulement | `FUNCTIONAL_PARTIAL` | Reprendre le worktree et intégrer une prévisualisation |
|
||||
| LoutreHome | Pièces, appareils, scènes simulées, événements | 14 backend + build relancés | Fiche seulement | `FUNCTIONAL_PARTIAL` | Compléter capteurs/automatisations et expliciter les connecteurs simulés |
|
||||
| AutoCare | Véhicules, kilométrage, entretiens, dépenses et rappels | 25 backend + build relancés | Fiche seulement | `FUNCTIONAL_PARTIAL` | Reprendre le worktree et intégrer une prévisualisation |
|
||||
| Smart Inventory | Objets, emplacements, documents, recherche, QR et CSV | 23 backend + build relancés | Fiche seulement | `FUNCTIONAL_PARTIAL` | Reprendre le worktree et intégrer une prévisualisation |
|
||||
| Knowledge Graph | Nœuds, relations, graphe, recherche, filtres, import | 13 backend + build relancés | Fiche seulement | `FUNCTIONAL_PARTIAL` | Ajouter le lien LoutreBrain et intégrer une prévisualisation |
|
||||
| TripOrganizer | Voyages, étapes, réservations, dépenses et checklist | 17 backend + build relancés | Fiche seulement | `FUNCTIONAL_PARTIAL` | Compléter documents/carte et intégrer une prévisualisation |
|
||||
| PWA Factory | Éditeur, modèles, persistance, aperçu, manifest, SW et ZIP autonome | 4 métier + suite globale relancés | Route CodexPi prête dans le commit | `TESTING` | Déployer en environnement de recette après autorisation, puis tester sur iPhone |
|
||||
| NASFLIX MediaHealth | Lecture/audit partiel Jellyfin et fichiers | Tests connexes seulement | NASFLIX partiel | `FUNCTIONAL_PARTIAL` | Reprendre la tâche en pause sans aucune suppression de média |
|
||||
| NASFLIX AI Media Curator | Catalogue, préférences et recommandations | Aucune acceptation complète retrouvée | NASFLIX partiel | `FUNCTIONAL_PARTIAL` | Reprendre la tâche en pause et ajouter l'historique testé |
|
||||
| Pi Doctor | Collecte, snapshots, incidents, plans immuables, diagnostic et décision persistante | 38 backend + 3 frontend + 4 navigateur ; build/HTTP validés | Commit et preview loopback disponibles ; service hôte/Docker et ingestion CodexPi réels non validés | `TESTING` | Recette hôte privée après autorisation, puis test du collecteur systemd et de l'ingestion réelle |
|
||||
103
docs/application-deployment-plan.md
Normal file
103
docs/application-deployment-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Plan de recette et de déploiement des applications Loutre
|
||||
|
||||
Ce document prépare les opérations ; il ne les autorise pas. Aucun déploiement de production, redémarrage CodexPi, changement QNAP/Jellyfin ou exposition publique ne doit être exécuté sans accord explicite.
|
||||
|
||||
## 1. Conditions d'entrée
|
||||
|
||||
Une application peut entrer en recette uniquement si sa branche contient un commit identifié, si son worktree est propre hors artefacts ignorés, si ses tests métier et son build passent à nouveau depuis ce commit et si ses limites matérielles sont documentées. Le statut reste au maximum `TESTING` avant cette recette.
|
||||
|
||||
Pour les connecteurs QNAP, Jellyfin, Docker, SMB, Home Assistant ou réseau, la recette commence avec des fixtures et un compte ou jeton de lecture seule. Une simulation doit être étiquetée comme telle dans l'interface. Aucun média, virtual host, certificat, appareil ou montage n'est modifié pendant cette étape.
|
||||
|
||||
## 2. Sauvegardes avant changement
|
||||
|
||||
1. Arrêter toute nouvelle tâche de déploiement et attendre la fin de la session Codex active.
|
||||
2. Enregistrer le SHA de CodexPi, le SHA de l'application et les versions d'images actuellement actives.
|
||||
3. Copier les bases SQLite avec leur méthode de sauvegarde cohérente (`VACUUM INTO` ou API de sauvegarde SQLite), puis vérifier `PRAGMA integrity_check` sur la copie.
|
||||
4. Sauvegarder les volumes applicatifs concernés sans inclure les jetons, cookies ou profils dans les journaux de preuve.
|
||||
5. Exporter la configuration Compose résolue en masquant les variables sensibles.
|
||||
6. Pour le reverse proxy QNAP, obtenir séparément une sauvegarde en lecture seule des fichiers autorisés. Aucune écriture NAS n'est incluse dans le déploiement CodexPi.
|
||||
|
||||
Les sauvegardes portent un horodatage UTC et sont conservées hors des worktrees Git. Un test de lecture est obligatoire avant de poursuivre.
|
||||
|
||||
## 3. Recette isolée
|
||||
|
||||
Chaque application est construite depuis son commit dans un projet Compose distinct, avec un nom de projet unique, un volume de recette neuf et un port lié uniquement à `127.0.0.1`. Une seule application lourde est démarrée à la fois sur le Raspberry Pi.
|
||||
|
||||
La recette vérifie :
|
||||
|
||||
- santé HTTP et démarrage sans migration destructive ;
|
||||
- authentification et isolation entre utilisateurs ;
|
||||
- création, modification, réouverture après redémarrage et suppression lorsque prévue ;
|
||||
- erreurs de validation et indisponibilité des connecteurs ;
|
||||
- build frontend, navigation mobile 390 px et absence d'erreur JavaScript ;
|
||||
- absence de bouton essentiel fictif ;
|
||||
- persistance sur le volume de recette ;
|
||||
- limites CPU/RAM et taille des journaux ;
|
||||
- export/import ou sauvegarde spécifique à l'application ;
|
||||
- URL interne d'ouverture depuis le catalogue CodexPi.
|
||||
|
||||
Les applications d'infrastructure comparent les valeurs affichées à la source autorisée. Une valeur issue d'une fixture ne valide jamais le connecteur réel.
|
||||
|
||||
## 4. Passage contrôlé
|
||||
|
||||
Après présentation des preuves, l'utilisateur choisit explicitement l'application et la fenêtre de déploiement. Le changement utilise une nouvelle image immuable étiquetée avec le SHA, puis un remplacement ciblé du seul service concerné. Il n'inclut jamais `docker compose down -v`, un redémarrage du Pi/NAS, une modification SSH/pare-feu ou une modification automatique du reverse proxy QNAP.
|
||||
|
||||
Les contrôles immédiats sont : santé, connexion, lecture de données existantes, écriture d'une donnée de contrôle réversible, réouverture, journaux sans secret et lien « Ouvrir » du catalogue. `READY_V0` n'est attribué qu'après leur réussite.
|
||||
|
||||
## 5. Rollback
|
||||
|
||||
Le rollback restaure l'image précédente et la configuration Compose précédente. Si une migration de données a été appliquée, son plan spécifique doit être testé avant le déploiement ; à défaut, l'application repasse en lecture seule et la base sauvegardée est restaurée dans un volume distinct pour comparaison. Les volumes actuels ne sont jamais supprimés automatiquement.
|
||||
|
||||
Un échec de santé, une perte d'authentification, une erreur de persistance, une consommation anormale ou une divergence avec une source réelle déclenche le rollback. L'incident et les commandes réellement exécutées sont ajoutés à l'historique, sans valeur secrète.
|
||||
|
||||
## 6. Ordre proposé
|
||||
|
||||
1. PWA Factory, déjà en `TESTING`.
|
||||
2. Pi Doctor en mode collecte/diagnostic uniquement.
|
||||
3. LoutreOS en lecture seule.
|
||||
4. Codex Commander et Autonomous Dev Studio.
|
||||
5. Applications CRUD locales : LoutreFinance, Smart Inventory, AutoCare, Knowledge Graph, PrintPilot, TripOrganizer et LoutreHome.
|
||||
6. Connecteurs réseau ou externes : NetworkGuardian, LoutreBrain, Reverse Proxy Manager et modules NASFLIX.
|
||||
|
||||
Cet ordre limite les risques : les intégrations QNAP, réseau et médias restent les dernières et conservent leur mode lecture seule tant qu'une validation séparée n'est pas accordée.
|
||||
|
||||
## 7. Registre et workflow préparé
|
||||
|
||||
Le registre central `application_registry` contient exactement les 17 applications métier ; le portail App Store reste un composant de CodexPi et n'est pas compté comme une dix-huitième application. Chaque ligne conserve l'identifiant du portefeuille, le type, le répertoire cible, le commit, les stacks backend/frontend, l'URL interne, la route d'ouverture, les preuves de tests, les dépendances, le statut et les limites de déploiement.
|
||||
|
||||
Les statuts de mise en service sont distincts des statuts de développement :
|
||||
|
||||
- `DEVELOPMENT_READY` : code récupérable, mais V0 ou preuves encore incomplètes ;
|
||||
- `TESTING` : validations isolées en cours ou terminées sans recette cible ;
|
||||
- `INTEGRATION_READY` : commit, tests métier, persistance et route prêts pour recette ;
|
||||
- `DEPLOYED` : révision réellement démarrée dans l'environnement déclaré ;
|
||||
- `OPERATIONAL` : healthchecks, route, HTTPS et scénarios métier vérifiés sur la cible ;
|
||||
- `BLOCKED` : preuve ou dépendance indispensable absente.
|
||||
|
||||
Les API `/api/application-registry` et `/api/application-registry/mission` exposent respectivement le registre et la supervision de la file. La préparation d'un déploiement crée un enregistrement `PREPARED` et dix étapes persistantes : sauvegarde, dépendances, migrations, configuration, démarrage, healthcheck, routes, HTTPS, smoke test et rollback. Elle n'exécute aucune commande. Une cible doit être privée, le commit doit correspondre au registre et une préparation de production exige `INTEGRATION_READY`.
|
||||
|
||||
Les plans LoutreOS, Pi Doctor, Reverse Proxy Manager et NASFLIX embarquent en plus une liste structurée de contrôles de connecteurs. Chaque contrôle précise le mode autorisé (`read-only`, Docker rootless, diagnostic uniquement ou brouillon) et la preuve attendue. Ces lignes restent des exigences de recette : leur présence dans un plan ne signifie jamais que le Raspberry Pi, QNAP ou Jellyfin a été contacté.
|
||||
|
||||
`DEPLOYED` et `OPERATIONAL` ne peuvent pas être saisis manuellement. Leur future promotion devra provenir du workflow exécuté après autorisation, avec preuves attachées à chaque étape. Ainsi, des tests unitaires verts ne suffisent jamais à rendre une application opérationnelle.
|
||||
|
||||
## 8. Tableau de mise en service des 17 applications
|
||||
|
||||
| Projet | Code | Tests | Intégration | Déploiement | Opérationnel |
|
||||
|---|---|---|---|---|---|
|
||||
| LoutreOS | Commit `2021e40`, collecteur/FastAPI/React | 56 backend, 7 frontend, 2 navigateur, persistance et HTTP validés | Route réelle CodexPi et connecteurs Pi/Docker/QNAP/Jellyfin cible manquants | `TESTING`, aucune cible déployée | **NON** — sources réelles externes non testées |
|
||||
| NetworkGuardian | Worktree FastAPI/React existant | 29 backend et build ; parcours cible à refaire | URL CodexPi, découverte autorisée et carte réseau cible manquantes | `DEVELOPMENT_READY` | **NON** — réseau réel non vérifié |
|
||||
| Reverse Proxy Manager | Worktree FastAPI/React et parseur Apache | 25 backend et 6 navigateur conservés | Source QNAP en lecture seule, certificats et workflow de validation manquants | `TESTING` | **NON** — QNAP non connecté |
|
||||
| Codex Commander | Module CodexPi et application isolée existants | 12 backend/build ; navigateur incomplet | Unification, collaboration et reprise réelle à valider | `DEVELOPMENT_READY` | **NON** — session V0 cible non validée |
|
||||
| Autonomous Dev Studio | Module CodexPi fonctionnel partiel | Tests intégrés, aucun parcours complet jusqu'à preview | Versionnement, correction automatique et preview bout en bout manquants | `DEVELOPMENT_READY` | **NON** — aucune application complète produite en recette |
|
||||
| LoutreBrain | Worktree FastAPI/FTS5/React existant | 18 backend et build ; navigateur à refaire | Recherche sémantique, index CodexPi et route réelle manquants | `TESTING` | **NON** — moteur cible non validé |
|
||||
| LoutreFinance | Worktree Django/React existant | 17 Django et 2 navigateur conservés | Revalidation persistance, route CodexPi et recette privée manquantes | `TESTING` | **NON** — aucune cible démarrée |
|
||||
| PrintPilot | Worktree FastAPI/React existant | 37 backend et build | Route, preview et connecteurs matériels explicites manquants | `DEVELOPMENT_READY` | **NON** — aucune imprimante réelle testée |
|
||||
| LoutreHome | Worktree FastAPI/React existant | 14 backend et build | Capteurs/automatisations, route et Home Assistant/MQTT cible manquants | `DEVELOPMENT_READY` | **NON** — données simulées uniquement |
|
||||
| AutoCare | Worktree FastAPI/React existant | 25 backend et build | Route, documents/assurances et preview cible à valider | `DEVELOPMENT_READY` | **NON** — aucune cible démarrée |
|
||||
| Smart Inventory | Worktree FastAPI/React existant | 23 backend et build | Route, photos/documents et restauration cible à valider | `DEVELOPMENT_READY` | **NON** — aucune cible démarrée |
|
||||
| Knowledge Graph | Worktree FastAPI/React/SVG existant | 13 backend et build | Lien LoutreBrain, route et parcours mobile cible manquants | `DEVELOPMENT_READY` | **NON** — aucune cible démarrée |
|
||||
| TripOrganizer | Worktree FastAPI/React existant | 17 backend et build | Documents, carte optionnelle, route et mode hors ligne cible manquants | `DEVELOPMENT_READY` | **NON** — aucune cible démarrée |
|
||||
| PWA Factory | Commit `7f31d2c`, éditeur intégré | Tests CRUD/export ZIP et démarrage de l'export réussis | Recette HTTPS/iPhone et validation visuelle cible manquantes | `TESTING` | **NON** — non déployée et installation iPhone non testée |
|
||||
| NASFLIX MediaHealth | Code partiel dans NASFLIX | Tests connexes uniquement | Rapport, historique, corruption potentielle et Jellyfin réel manquants | `DEVELOPMENT_READY` | **NON** — aucune analyse cible complète |
|
||||
| NASFLIX AI Media Curator | Module NASFLIX partiel | Acceptation dédiée absente | Historique, collections brouillon et Jellyfin cible à valider | `DEVELOPMENT_READY` | **NON** — recommandations cibles non vérifiées |
|
||||
| Pi Doctor | Commit `a5dc22e`, collecteurs, FastAPI/React et module CodexPi | 38 backend, 3 frontend, 4 navigateur, build et HTTP loopback validés | systemd, Docker cible, ingestion CodexPi et session spécialisée réels restent à valider | `TESTING` | **NON** — service hôte non installé et connecteurs réels non testés |
|
||||
68
docs/architecture.md
Normal file
68
docs/architecture.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Architecture
|
||||
|
||||
CodexPi utilise quatre services applicatifs sur un réseau Compose privé.
|
||||
|
||||
| Service | Rôle | Port conteneur | Publication hôte |
|
||||
|---|---|---:|---|
|
||||
| `nginx` | reverse proxy unique | 8080 | `0.0.0.0:8765` (LAN) |
|
||||
| `django-web` | interface React, authentification et sessions Django | 8001 | aucune |
|
||||
| `api` | FastAPI/Uvicorn, REST, WebSockets, terminal, Git, Docker, Codex | 8000 | aucune |
|
||||
|
||||
nginx envoie `/api/auth/*`, `/api/bootstrap` et les fichiers de l'interface à Django. Les autres routes `/api/*` et `/ws/*` vont à FastAPI. FastAPI valide directement la session Django stockée en base et exige le jeton CSRF de la session pour les mutations et WebSockets.
|
||||
|
||||
Le frontend React est compilé dans l'image puis servi par Django. Les données persistantes sont dans `./data` : base Django, base CodexPi, sessions JSONL et journal de sécurité. Le conteneur API monte uniquement la racine de projets autorisée, l'identité Codex existante et le socket Docker nécessaire à la page Docker. Le bind de `/home/config` utilise une propagation `rslave` : les supports montés sous cette racine sur l'hôte, y compris après le démarrage de l'API, deviennent visibles au même chemin dans le conteneur sans propager en retour les montages du conteneur vers l'hôte.
|
||||
|
||||
Le connecteur de machine distante ouvre uniquement des requêtes sortantes vers nginx. Les tâches `list`, `read` et `write` transitent par une file SQLite ; aucun terminal ni port entrant n'est exposé sur le PC associé.
|
||||
|
||||
Le bridge IA PC suit un modèle différent parce qu’OpenCode doit conserver le
|
||||
stream HTTP d’Ollama pendant l’inférence. Une association à usage unique
|
||||
enregistre l’adresse privée du PC et un jeton chiffré côté CodexPi. Le proxy
|
||||
Python du PC écoute sur le LAN, authentifie chaque requête et n’autorise que les
|
||||
routes Ollama de découverte et de génération ; l’API Ollama brute reste liée à
|
||||
`127.0.0.1`. CodexPi produit sous `data/local-ai/` un fichier OpenCode et un
|
||||
jeton privés, puis les transmet uniquement aux workers OpenCode. Un seul bridge
|
||||
est actif à la fois afin de rendre le routage et le modèle par défaut
|
||||
déterministes.
|
||||
|
||||
Les tâches Codex écrivent un flux JSONL persistant et peuvent reprendre après fermeture du navigateur. Le terminal utilise tmux lorsqu'il est disponible. Un projet est toujours identifié par UUID ; les chemins sont canonisés côté serveur et contrôlés contre les racines autorisées/interdites.
|
||||
|
||||
L’ordonnanceur autorise par défaut trois moteurs Codex simultanés pour trois projets distincts. Des verrous de fichiers partagés entre les workers imposent à la fois la capacité globale configurée par `CODEXPI_MAX_CONCURRENT_AGENTS` et l’exclusion mutuelle au niveau du projet. Les trois espaces globaux (Agent maître, Agent Raspberry Pi et Agent Bibliothécaire) restent des projets indépendants : leur marqueur réservé `__global_agent__` sert uniquement à l’interface et ne crée pas de verrou partagé. Un groupe associe explicitement plusieurs projets locaux du même propriétaire grâce à la relation plusieurs-à-plusieurs `project_group_members` ; un projet peut donc participer à plusieurs groupes. Une tâche acquiert, dans un ordre stable, tous les verrous de ses groupes afin d’éviter les interblocages et les exécutions concurrentes sur une ressource partagée. Les chemins des autres membres sont injectés comme références de lecture pour Codex SAFE, sans être ajoutés aux racines d’écriture du sandbox, et les derniers comptes rendus alimentent un contexte commun asynchrone. Pour un projet en `FULL ACCESS`, ces chemins sont également injectés quel que soit le moteur avec une interdiction conversationnelle d’écrire ailleurs sans demande explicite ; le backend ne présente pas cette consigne comme une isolation, car le sandbox est désactivé. Les autres moteurs en SAFE ne reçoivent que les noms et comptes rendus. Ainsi, plusieurs projets indépendants avancent en parallèle et les membres d’un groupe restent sérialisés lorsqu’ils pilotent la même ressource.
|
||||
|
||||
Les orchestrations sont des machines à états persistantes dans SQLite. Les validations d’ébauche utilisent une empreinte de version ; les tests et la recette sont liés au commit vérifié. Une correction réutilise la discussion, la branche et le worktree existants. Une approbation est invalidée dès que la révision change.
|
||||
|
||||
Le chantier autonome de remédiation possède sa propre machine à états persistante (`remediation_runs`, `remediation_step_runs`, `remediation_events`, `remediation_self_repairs`). Un seul chantier peut être actif par propriétaire. Une boucle backend loue brièvement le chantier, attend la fin de la tâche courante, puis alterne agent projet et Agent maître. Le maître rend un verdict structuré `approve`, `correct` ou `block`; une correction réutilise la conversation du projet et le cycle est borné à trois reprises. Tout blocage est transmis à `CodexPi (Self)` dans une conversation persistante propre au chantier. La boucle surveille aussi cette tâche lorsque le chantier est `BLOCKED`; un verdict structuré `fixed` peut ajouter une précision bornée au prompt courant puis reprendre automatiquement le même fil, tandis que `needs_user` laisse le chantier bloqué avec une raison visible. Les auto-réparations sont bornées à trois incidents par chantier et leur relance de format à une tentative. Une reprise bloquée peut rebaser les textes du plan courant, mais le backend refuse toute modification du nombre, de l’ordre, de la cible ou du niveau de risque des étapes ; les conversations et preuves existantes sont conservées. Les étapes restent séquentielles pour respecter leurs dépendances, mais elles utilisent l’ordonnanceur normal : les autres projets et agents peuvent continuer en parallèle dans la limite globale. Le dernier état, les discussions, les auto-réparations et les événements survivent au redémarrage de l’API et à la fermeture de la PWA.
|
||||
|
||||
Le centre de coordination repose sur `agent_decisions`, `agent_incidents`, `agent_runtime_policies`, `agent_project_policies`, `specialist_agents` et `specialist_delegations`. À la fin d’une tâche, le worker interprète uniquement deux marqueurs JSON stricts : une demande de décision et un appel de compétence. Leur enregistrement appartient à la même transaction que la fin de la tâche ; une panne du sous-système de coordination ne peut toutefois pas empêcher la tâche principale de se terminer. Une décision met en pause la branche de délégation éventuelle et sa réponse est réinjectée dans la même conversation. La boucle de coordination surveille les réparations Self, l’auto-construction des spécialistes et les délégations. Une délégation imbriquée reprend d’abord le fil du spécialiste appelant, puis le résultat final remonte au projet source. La profondeur maximale vaut deux. Un bail SQLite court (`agent_coordination_lease`) garantit qu’une seule instance traite ces transitions pendant une bascule blue/green ; le bail expire automatiquement si l’instance disparaît.
|
||||
|
||||
Les politiques de ressources s’appliquent dans `session_worker` avant l’acquisition d’un emplacement moteur. Elles ordonnent les tâches en attente, limitent le nombre de moteurs simultanés, suspendent l’admission sous pression CPU/mémoire et réservent les tâches d’arrière-plan à leur fenêtre horaire. Les verrous déjà acquis et les processus en cours ne sont jamais retirés. Le budget de durée alimente un signal persistant et une notification, sans envoyer de signal au processus ni modifier son statut. Les préférences de notifications sont enregistrées par utilisateur et filtrées avant l’ajout à la file Web Push.
|
||||
|
||||
Un spécialiste est représenté par un projet global `__global_agent__` distinct, un dossier sous `data/specialists/` et une discussion de construction. Son projet est créé en SAFE : il écrit seulement dans son atelier et reçoit le chemin source comme référence de lecture. Le résultat revient au projet par une nouvelle tâche de conversation ; l’agent source reste l’unique intégrateur. Désactiver un spécialiste empêche les nouvelles délégations sans supprimer son atelier ni ses fils.
|
||||
|
||||
Le canal de l’agent maître ne passe ni par un projet ni par le socket Docker de l’API. Un petit service hôte écoute un socket Unix sous `data/host-agent/`, authentifie chaque requête avec un jeton `0600` et exécute le CLI sous son identité système dédiée. L’API impose en plus l’authentification administrateur, CSRF et une confirmation par demande privilégiée. Le service n’est pas activé automatiquement par Compose.
|
||||
|
||||
La réconciliation de stockage est séparée du runtime applicatif. Son inventaire
|
||||
lit les bases SQLite en mode `mode=ro`, recoupe les chemins persistés avec les
|
||||
worktrees Git et les verrous, puis calcule les empreintes uniquement lorsqu'un
|
||||
candidat de même catégorie, nom logique et taille existe dans une autre
|
||||
instance. La quarantaine éventuelle utilise un verrou `flock`, revalide inode,
|
||||
mtime, taille et empreinte contre le plan, puis effectue un renommage atomique
|
||||
vers `data/quarantine/<reçu>/payload`. Un manifeste `0600`, une date
|
||||
d'éligibilité après grâce et un audit JSONL permettent la restauration. Si
|
||||
l'audit échoue, le renommage est annulé avant de rendre l'erreur. Sous le verrou,
|
||||
un second inventaire relit les bases et refuse le déplacement si une référence,
|
||||
une activité ou une exclusion est apparue depuis le dry-run. Une base absente
|
||||
ou illisible, ainsi qu'un schéma sans les tables et colonnes de référence
|
||||
attendues, fait échouer la classification de toute l'instance en mode fermé.
|
||||
Pendant toute la revalidation et le renommage, une transaction
|
||||
`BEGIN IMMEDIATE` est maintenue sur chaque base dans un ordre stable : aucune
|
||||
nouvelle référence SQLite ne peut être admise entre le contrôle et le mouvement.
|
||||
L'inventaire vérifie chaque composant jusqu'à `data/` avec `lstat` et ne parcourt
|
||||
jamais une instance dont ce parent est symbolique.
|
||||
|
||||
Les caches Chromium mutualisables sont isolés du profil (cookies, historique,
|
||||
sessions) sous `data/browser-cache/<version majeure>/`. Seuls `Cache`,
|
||||
`Code Cache` et `GPUCache` peuvent être rapprochés, et jamais lorsqu'un verrou
|
||||
navigateur est détenu. Les volumes `browser-home` existants restent privés et
|
||||
hors inventaire implicite.
|
||||
|
||||
Le worker spécialisé `host_session_worker` relie à ce canal les conversations du seul projet global privilégié Pi Doctor/Agent Raspberry Pi. Il conserve les tables `conversations`, `messages` et `prompt_queue`, les verrous de projet et la limite globale d’agents ; seule l’exécution du moteur quitte le conteneur. Le chantier autonome peut ainsi reprendre le même fil après un blocage technique et soumettre le résultat hôte à l’Agent maître. Les autres projets continuent d’utiliser `session_worker` dans le conteneur.
|
||||
108
docs/audit-interface-fonctionnel-2026-11-12.md
Normal file
108
docs/audit-interface-fonctionnel-2026-11-12.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Audit visuel et fonctionnel final de CodexPi
|
||||
|
||||
Audit initial : 12 novembre 2026
|
||||
Corrections et contre-audit : 13 novembre 2026
|
||||
|
||||
## Périmètre
|
||||
|
||||
Le contrôle couvre la maquette de référence, l’interface CodexPi actuelle, la V1 au commit `445128c`, les routes API, les droits d’accès, les parcours desktop et mobile, les dépendances et les tests automatisés. Les actions destructives ou externes — déploiement réel, arrêt de conteneur, révocation d’une machine et commandes sur l’hôte — ont été vérifiées dans le code et par tests isolés, sans être exécutées sur l’instance en service. Aucun redémarrage ni déploiement n’a été effectué.
|
||||
|
||||
## Verdict sur l’interface
|
||||
|
||||
Le principe « entreprise d’agents » est pertinent pour **Organisation**, **Activité** et **Projets** : il rend visibles le propriétaire, la coordination, les groupes, l’infrastructure et le travail en cours.
|
||||
|
||||
Il serait en revanche mauvais de forcer ce canevas sur le chat, le diff Git, le terminal ou l’exploitation Docker. Ces écrans demandent plus de densité et moins de décoration. CodexPi conserve donc un langage commun — navigation, couleurs, en-têtes, états — tout en gardant des surfaces spécialisées et un mode focus pour le travail profond. C’est le bon compromis entre la maquette et la V1.
|
||||
|
||||
## Organisation : logique finale
|
||||
|
||||
Le fonctionnement est désormais cohérent avec le besoin « groupe TV » :
|
||||
|
||||
1. **+ Groupe** ouvre une fenêtre accessible et sélectionne au moins deux projets locaux existants.
|
||||
2. Les projets doivent être actifs, appartenir au même propriétaire et rester en mode SAFE.
|
||||
3. Un projet peut participer à plusieurs groupes. L’ajouter à « TV » ne le retire donc pas de « Médias » ou « Salon ».
|
||||
4. Un groupe peut être créé, modifié ou supprimé sans supprimer ses projets.
|
||||
5. Codex SAFE reçoit les chemins des autres membres et peut lire leur code, mais seul le projet courant reste une racine d’écriture.
|
||||
6. Claude et OpenCode reçoivent les noms et les comptes rendus, sans chemins inter-projets, car leur frontière d’écriture n’est pas équivalente.
|
||||
7. `FULL ACCESS` est refusé avant l’entrée dans un groupe et ne peut plus être activé après l’entrée.
|
||||
8. La réponse finale d’une tâche devient un compte rendu persistant consultable par les autres membres lors de leur tâche suivante.
|
||||
9. Une tâche acquiert tous les verrous des groupes auxquels son projet appartient, dans un ordre stable. Les moteurs Codex, Claude et OpenCode ne peuvent donc pas travailler simultanément sur des projets qui partagent une même ressource.
|
||||
10. Les groupes, membres, propriétaires, activités et états système affichés dans Organisation proviennent des API réelles.
|
||||
|
||||
La communication entre agents reste volontairement **asynchrone** : ce sont des comptes rendus persistés, pas une conversation directe entre processus. Le fonctionnement du bac à sable `workspace-write` utilisé pour Codex SAFE est décrit dans la [documentation OpenAI](https://learn.chatgpt.com/docs/sandboxing).
|
||||
|
||||
## Corrections issues de l’audit
|
||||
|
||||
| Priorité | Constat initial | Correction livrée |
|
||||
|---|---|---|
|
||||
| P0 | Dépendances Python et frontend vulnérables | Django, FastAPI, Uvicorn, multipart, Vite, Sharp, pytest et Setuptools mis à niveau ; audits Python et npm à zéro vulnérabilité connue ; contrôles ajoutés à la CI. |
|
||||
| P0 | Lecture seule non garantie en FULL ACCESS | Combinaison groupe/FULL ACCESS refusée dans les deux sens. |
|
||||
| P0 | Isolation différente selon le moteur | Chemins inter-projets réservés à Codex SAFE ; autres moteurs limités aux comptes rendus ; verrouillage de groupe appliqué à tous les moteurs. |
|
||||
| P1 | Groupes indirects et appartenance unique | Tables `project_groups` et `project_group_members`, migration de l’existant et appartenance plusieurs-à-plusieurs. |
|
||||
| P1 | Navigation React non reflétée dans l’URL | Routes centralisées, liens profonds, `pushState`, `popstate`, Retour, rechargement et titre de document. |
|
||||
| P1 | Propriétaire ambigu en vue administrateur | Propriétaire affiché sur les groupes et projets concernés. |
|
||||
| P1 | État NasPi décoratif | Statut relié aux données réelles du tableau de bord. |
|
||||
| P1 | Navigation mobile trop chargée | Cinq destinations principales et menu **Plus** ; boutons tactiles de 44 px et fenêtres adaptées à 375 px. |
|
||||
| P1 | Typographie trop petite | Corps, métadonnées et contrôles agrandis tout en conservant une densité desktop raisonnable. |
|
||||
| P1 | Accessibilité incomplète | Icônes SVG, lien d’évitement, `aria-current`, focus piégé/restauré, fermeture Échap, fenêtres partagées et contrôle axe desktop/mobile. |
|
||||
| P1 | Mélange français/anglais | Libellés de navigation, espace de travail, Git, statuts, métriques, états réseau et écrans d’exploitation harmonisés en français. |
|
||||
| P1 | Lanceur limité à des raccourcis locaux | Recherche API sur projets, conversations et groupes, avec filtrage par propriétaire et déduplication des requêtes. |
|
||||
| P1 | Polling redondant en arrière-plan | Cache partagé, requêtes en vol mutualisées et suspension quand l’onglet ou la zone n’est pas visible. |
|
||||
| P1 | Erreurs réseau répétitives ou ambiguës | Distinction appareil/API, état persistant et notifications dédupliquées. |
|
||||
| P1 | Absence de tests de parcours | Playwright desktop/mobile, création de groupe, URL/Retour/rechargement, clavier, axe et captures de non-régression. |
|
||||
| P2 | Paquet principal d’environ 502 kB | Chargement dynamique par route ; paquet principal réduit à 130,89 kB brut / 36,17 kB gzip. Markdown et terminal restent dans des blocs différés. |
|
||||
| P2 | Écosystème sans hiérarchie | Regroupement en **Produits**, **Exploitation** et **Construction**, avec URL interne persistante. |
|
||||
| P2 | Surfaces visuelles incohérentes | Tokens communs, modes Tableau de bord/Atelier/Revue Git et mode focus persistant. |
|
||||
| P2 | Écrans monolithiques et polling local | Hooks de visibilité, service API partagé, parseur de commandes et logique de routes extraits et testés. |
|
||||
| P2 | Orchestrateur fragile sur les commandes citées | Parseur conservant guillemets, espaces échappés, arguments vides et chemins Windows ; erreurs d’historique affichées. |
|
||||
| P2 | Agent maître peu suivi | Rafraîchissement actif pendant une exécution et distinction explicite avec l’orchestrateur. |
|
||||
| P2 | Machines distantes dépendantes du projet sélectionné | Vraie vue globale des machines avec choix explicite du profil de départ. |
|
||||
| P2 | Registre peu lisible sur mobile et sans historique | Tableau transformé en cartes mobiles, fenêtre accessible et historique réel des préparations/étapes. |
|
||||
| P2 | App Store visuellement isolé | Branding CodexPi, fenêtre commune et repli lisible en cas d’icône absente. |
|
||||
|
||||
## Contre-audit par écran
|
||||
|
||||
| Écran | Résultat final | Point de vigilance assumé |
|
||||
|---|---|---|
|
||||
| Organisation | Hiérarchie claire, données réelles, groupes multiples, création/édition/suppression, propriétaires et relais visibles. | Les relais sont asynchrones afin de rester auditables et reproductibles. |
|
||||
| Activité | Recherche, filtres, tableau/flux, revue et états réseau distincts. | Le tableau reste réservé aux grands écrans ; le mobile utilise le flux. |
|
||||
| Projets | Recherche, tri, activité, archives, métriques traduites et fiches mobiles. | Aucun défaut bloquant identifié. |
|
||||
| Atelier / Chat | Files, reprise WebSocket, pièces jointes, contexte, erreurs, lecture vocale et mode focus. | Les messages techniques renvoyés par un moteur externe peuvent conserver son vocabulaire propre. |
|
||||
| Git / Revue | Diff, restauration, preuves, validation Git et personnalité Revue dédiée. | Les opérations destructives restent soumises à confirmation. |
|
||||
| Navigateur / Terminal / Docker | États, reconnexion, périmètre projet et actions sensibles explicites. | Les commandes réelles n’ont pas été lancées pendant l’audit. |
|
||||
| Orchestrateur | Historique sûr, états vides, arguments fiables, validations et barrières de fusion. | Une mise en production n’est jamais implicite. |
|
||||
| Agent maître | Installation volontaire, indisponibilité claire et suivi actif. | Reste réservé au propriétaire de l’hôte. |
|
||||
| Serveur / Pi Doctor | Statut global réel, libellés harmonisés et polling borné. | Les réparations restent désactivées hors plan validé. |
|
||||
| Écosystème | Navigation hiérarchisée et liens profonds. | Chaque outil conserve sa densité métier au lieu d’imiter artificiellement Organisation. |
|
||||
| App Store | Recherche, PWA, branding et repli d’icône cohérents. | Aucun défaut bloquant identifié. |
|
||||
| Mise en service | Préparation distincte du déploiement, cartes mobiles et historique des plans. | L’interface ne prétend jamais qu’un plan préparé a été exécuté. |
|
||||
| Dev Studio | Plan, empreinte, approbation, branche, tests et rapport restent séparés de la fusion et du déploiement. | Aucun déploiement réel durant l’audit. |
|
||||
| Machines distantes | Liste globale, jumelage, révocation et consultation hors ligne. | Le profil local de départ doit être choisi pour un nouveau jumelage. |
|
||||
| Réglages | Navigation compacte, icônes cohérentes et libellés français. | Aucun défaut bloquant identifié. |
|
||||
| Connexion / initialisation | CSRF, sessions, clavier et erreurs contrôlés. | La disponibilité réelle du serveur dépend naturellement du réseau privé. |
|
||||
|
||||
## V1 : éléments remigrés
|
||||
|
||||
Les qualités utiles de la V1 ont été reprises :
|
||||
|
||||
- trois personnalités réelles — Tableau de bord, Atelier et Revue Git ;
|
||||
- mode focus pour le chat, le code et le diff ;
|
||||
- navigation mobile limitée et fonctions secondaires sous **Plus** ;
|
||||
- flux Activité mobile ;
|
||||
- revue Git centrée sur le diff et les preuves ;
|
||||
- séparation nette entre navigation globale et contexte projet.
|
||||
|
||||
Les éléments à ne pas remigrer restent exclus : données factices, états décoratifs, barres latérales concurrentes, libellés anglais non harmonisés et plusieurs sélecteurs de projet pour la même action.
|
||||
|
||||
## Validation finale
|
||||
|
||||
- Backend : **300 tests réussis**, sans avertissement, dans l’image Docker finale.
|
||||
- Frontend : **42 tests réussis**.
|
||||
- Parcours navigateur : **8 tests Playwright réussis** sur 1440 × 900 et 375 × 812.
|
||||
- Accessibilité : aucune violation axe sérieuse ou critique sur le parcours Organisation contrôlé.
|
||||
- TypeScript et build de production : réussis.
|
||||
- Paquet principal : **130,89 kB brut / 36,17 kB gzip** ; CSS global **232,51 kB brut / 43,58 kB gzip**.
|
||||
- `npm audit` : **0 vulnérabilité**.
|
||||
- `pip-audit --local` : **aucune vulnérabilité connue**.
|
||||
- Captures de référence desktop et mobile enregistrées dans les tests E2E.
|
||||
|
||||
Le CSS global reste volumineux en valeur brute, mais il pèse 43,58 kB compressé et ne bloque pas l’affichage. Le prochain découpage éventuel de CSS par route relève désormais de l’optimisation continue, pas d’une anomalie fonctionnelle ou visuelle.
|
||||
70
docs/installation.md
Normal file
70
docs/installation.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Installation et accès
|
||||
|
||||
## Prérequis
|
||||
|
||||
- Raspberry Pi OS 64 bits et utilisateur Linux non-root ;
|
||||
- Docker Engine et plugin Docker Compose accessibles à cet utilisateur ;
|
||||
- Tailscale recommandé pour l'accès distant privé ;
|
||||
- réseau local de confiance pour l'accès direct par IP au port 8765 ;
|
||||
- compte du moteur choisi à authentifier après l’installation (Codex, Claude Code ou fournisseur OpenCode).
|
||||
|
||||
Python, Node.js, Django, FastAPI, Uvicorn, tmux, GitHub CLI, Codex CLI, Claude Code et OpenCode sont installés dans l'image. Aucun `.venv` n'est requis. Les unités systemd fournies ne font tourner aucun code applicatif en root : l’installateur les génère avec les UID/GID numériques du propriétaire de `/home/config/CodexPi`, puis elles démarrent Compose sous ce compte et surveillent le groupe du socket Docker. Aucun nom d’utilisateur particulier n’est imposé.
|
||||
|
||||
## Démarrage
|
||||
|
||||
```bash
|
||||
cd /home/config/CodexPi
|
||||
chmod +x scripts/*.sh
|
||||
./scripts/audit.sh
|
||||
./scripts/install.sh
|
||||
./scripts/compose.sh ps
|
||||
```
|
||||
|
||||
`install.sh` relève automatiquement l'UID/GID courant, le groupe du socket Docker et le dossier personnel contenant les profils des moteurs. Il construit l'image, applique les migrations Django, démarre les services et installe les unités de démarrage et d’auto-réparation. Le wrapper `scripts/compose.sh`, également utilisé au démarrage automatique, relève de nouveau le GID du socket à chaque invocation afin de conserver l'accès si Docker recrée le socket avec un autre groupe. Ouvrez ensuite CodexPi : l’assistant crée le premier administrateur sans commande supplémentaire.
|
||||
|
||||
L’unité de démarrage `codexpi.service` suit le cycle de vie de `docker.service`. Un redémarrage du démon Docker relance donc Compose avec le GID courant du socket au lieu de conserver le groupe d’un ancien conteneur. En complément, `codexpi-docker-access.timer` vérifie ce GID chaque minute et recrée uniquement l’API lorsqu’il a changé. La réparation est différée tant qu’une tâche Codex est active et ne démarre jamais une pile arrêtée volontairement. Ces unités s’exécutent sous le propriétaire non-root du projet, avec le groupe actuel du socket Docker ; elles ne lancent jamais Codex en root.
|
||||
|
||||
Sur une installation existante, activez une fois cette surveillance avec `./scripts/install-boot-service.sh`. Si Docker ou son socket est réellement arrêté ou absent, CodexPi attend simplement le prochain contrôle : aucun logiciel ne peut fournir les commandes Docker tant que le daemon lui-même est indisponible.
|
||||
|
||||
Les profils `.codex`, `.claude`, `.config/opencode` et `.config/gh` sont montés
|
||||
depuis le dossier personnel et survivent aux rebuilds. L’authentification d’un
|
||||
moteur reste une action interactive à effectuer dans le terminal CodexPi ; ne
|
||||
collez jamais de mot de passe ou de jeton dans une discussion.
|
||||
|
||||
Commandes utiles :
|
||||
|
||||
```bash
|
||||
./scripts/compose.sh up -d
|
||||
./scripts/compose.sh logs -f --tail=100
|
||||
./scripts/compose.sh restart
|
||||
./scripts/compose.sh down
|
||||
curl http://127.0.0.1:8765/proxy-health
|
||||
```
|
||||
|
||||
L'arrêt avec `./scripts/compose.sh down` conserve `./data`. N'ajoutez jamais `--volumes` sans sauvegarde.
|
||||
|
||||
## Accès direct sur le réseau local
|
||||
|
||||
Ouvrez `http://IP_DU_PI:8765` depuis un ordinateur du même réseau. Le port 8765 est publié par nginx uniquement ; FastAPI et Django restent privés dans Docker. N'ajoutez aucune redirection du port 8765 sur la box Internet. Si un pare-feu est actif sur le Pi, autorisez ce port uniquement depuis le sous-réseau local de confiance.
|
||||
|
||||
## Tailscale Serve recommandé
|
||||
|
||||
Gardez `CODEXPI_HOST=127.0.0.1` dans `.env`, puis :
|
||||
|
||||
```bash
|
||||
./scripts/tailscale-serve.sh --check
|
||||
./scripts/tailscale-serve.sh --apply
|
||||
```
|
||||
|
||||
Tailscale Serve termine HTTPS et relaie vers `http://127.0.0.1:8765`. Le script refuse de remplacer une configuration Funnel. Aucun compte, auth key, UPnP, DMZ ou transfert de port n'est créé.
|
||||
|
||||
Si Tailscale est absent, le script affiche les commandes d'installation sans les exécuter. L'association du Pi au tailnet reste une action interactive de l'utilisateur.
|
||||
|
||||
## Mise à jour
|
||||
|
||||
```bash
|
||||
cd /home/config/CodexPi
|
||||
./scripts/compose.sh build --pull
|
||||
./scripts/compose.sh up -d
|
||||
./scripts/security-audit.sh
|
||||
```
|
||||
85
docs/local-ai-pc-bridge.md
Normal file
85
docs/local-ai-pc-bridge.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Bridge PC IA local pour CodexPi
|
||||
|
||||
Le bridge permet à CodexPi d’utiliser les modèles Ollama installés sur un PC du
|
||||
réseau privé. Ollama reste lié à `127.0.0.1:11434` : seul le bridge authentifié
|
||||
écoute sur le réseau local. Le jeton généré pendant l’association est enregistré
|
||||
dans les espaces privés de CodexPi et du PC ; il ne contient aucun mot de passe
|
||||
CodexPi.
|
||||
|
||||
## Prérequis sur le PC
|
||||
|
||||
- Python 3.11 ou plus récent ;
|
||||
- Ollama démarré ;
|
||||
- au moins un modèle de conversation installé ;
|
||||
- le PC et le Raspberry Pi joignables sur le même LAN ou tailnet privé.
|
||||
|
||||
Vérification rapide sous Windows :
|
||||
|
||||
```powershell
|
||||
ollama list
|
||||
py --version
|
||||
```
|
||||
|
||||
## Association depuis la PWA
|
||||
|
||||
1. Ouvrez **Réglages → Comptes IA**.
|
||||
2. Dans **Serveur IA local sur PC**, choisissez **Ajouter un PC**.
|
||||
3. Téléchargez `codexpi_ai_bridge.py` et le fichier d’association
|
||||
`codexpi-ai.codexpi-ai` dans le même dossier.
|
||||
4. Ouvrez PowerShell dans ce dossier puis lancez :
|
||||
|
||||
```powershell
|
||||
py .\codexpi_ai_bridge.py --pairing .\codexpi-ai.codexpi-ai
|
||||
```
|
||||
|
||||
Sous macOS ou Linux :
|
||||
|
||||
```bash
|
||||
python3 ./codexpi_ai_bridge.py --pairing ./codexpi-ai.codexpi-ai
|
||||
```
|
||||
|
||||
Windows peut demander l’autorisation réseau pour Python. Autorisez uniquement
|
||||
les **réseaux privés**. Le port par défaut est `11435`; Ollama lui-même n’est pas
|
||||
publié sur le LAN.
|
||||
|
||||
Après association, CodexPi détecte les modèles installés. Choisissez le modèle
|
||||
par défaut puis utilisez **OpenCode · PC local** lors de la création d’une
|
||||
discussion.
|
||||
|
||||
## Redémarrage du bridge
|
||||
|
||||
L’association est conservée dans `~/.codexpi/ai-bridge.json`. Aux démarrages
|
||||
suivants, la commande ne nécessite plus le fichier temporaire :
|
||||
|
||||
```powershell
|
||||
py .\codexpi_ai_bridge.py
|
||||
```
|
||||
|
||||
Pour un démarrage automatique, créez un raccourci ou une tâche Windows qui
|
||||
exécute cette commande seulement après l’ouverture de session. Ne placez jamais
|
||||
le contenu de `~/.codexpi/ai-bridge.json` dans Git ou dans un partage public.
|
||||
|
||||
## Adresse ou port particuliers
|
||||
|
||||
Si le PC possède plusieurs interfaces réseau :
|
||||
|
||||
```powershell
|
||||
py .\codexpi_ai_bridge.py --pairing .\codexpi-ai.codexpi-ai `
|
||||
--advertise-address 192.168.1.20 --port 11435
|
||||
```
|
||||
|
||||
Le bridge refuse d’annoncer une adresse Internet publique. Pour Tailscale,
|
||||
indiquez l’adresse privée du PC visible depuis le Pi.
|
||||
|
||||
## Dépannage
|
||||
|
||||
- **Ollama ne répond pas** : ouvrez Ollama et vérifiez `ollama list`.
|
||||
- **Le Pi ne rejoint pas le bridge** : vérifiez le pare-feu privé Windows et le
|
||||
port `11435`, puis utilisez **Tester la connexion** dans CodexPi.
|
||||
- **Le modèle ne sait pas utiliser les outils** : choisissez un modèle dont les
|
||||
capacités Ollama contiennent `tools` et prévoyez un contexte suffisant.
|
||||
- **Le PC est éteint** : les comptes cloud restent disponibles ; les nouvelles
|
||||
tâches OpenCode locales échoueront proprement jusqu’au retour du bridge.
|
||||
|
||||
La révocation dans CodexPi efface sa copie chiffrée du jeton et retire le
|
||||
fournisseur OpenCode local. Arrêtez également le terminal du bridge sur le PC.
|
||||
49
docs/security.md
Normal file
49
docs/security.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Modèle de sécurité
|
||||
|
||||
CodexPi est un outil d'administration puissant. Il doit rester sur un réseau local de confiance ou derrière Tailscale Serve et ne doit jamais être directement exposé à Internet.
|
||||
|
||||
## Protections mises en œuvre
|
||||
|
||||
- seul nginx est publié sur le LAN au port `8765` ; FastAPI `8000` et Django `8001` restent internes à Docker ;
|
||||
- aucun UPnP, DMZ, Funnel ou transfert de port de box ;
|
||||
- sessions et authentification Django, mot de passe Argon2, cookies `Secure`, `HttpOnly`, `SameSite=Strict` ;
|
||||
- CSRF sur les mutations et contrôle d'origine des WebSockets ;
|
||||
- limite par IP, délai progressif et verrouillage temporaire après les échecs de connexion ;
|
||||
- journal JSONL en mode 0600 sans mot de passe, cookie, jeton Codex ou credential OpenAI ;
|
||||
- CSP, anti-framing, nosniff, politique de référent et permissions navigateur restrictives ;
|
||||
- conteneurs non-root, capacités Linux supprimées, système de fichiers racine en lecture seule et `no-new-privileges` ;
|
||||
- projets sous racines autorisées, résolution canonique, rejet des traversées et symlinks sortants ;
|
||||
- propagation unidirectionnelle des sous-montages de la racine de projets (`rslave`), sans propagation des montages du conteneur vers l'hôte ;
|
||||
- concurrence Codex bornée et sérialisation par projet pour éviter les écritures simultanées dans un même espace de travail ;
|
||||
- groupes limités à des projets locaux explicitement sélectionnés et appartenant au même propriétaire ; un projet peut rejoindre plusieurs groupes et les chemins des autres membres ne sont exposés qu’à Codex SAFE comme références de lecture, sans ajouter de racine d’écriture ;
|
||||
- groupes compatibles avec SAFE et `FULL ACCESS` : Codex SAFE reçoit les chemins voisins en lecture seule par sandbox ; en `FULL ACCESS`, les chemins sont transmis avec une consigne de consultation, sans prétendre fournir une frontière d’écriture ; Claude et OpenCode en SAFE ne reçoivent que les noms et comptes rendus inter-projets ;
|
||||
- processus lancés avec tableaux d'arguments, sans interpolation shell de saisie utilisateur ;
|
||||
- actions Git et Docker destructrices confirmées, aucune fonction prune globale ;
|
||||
- `FULL ACCESS` désactivé par défaut et confirmé explicitement ; dans ou hors d’un groupe, ce mode contourne le sandbox et le dossier courant ne constitue donc plus une frontière d’écriture ;
|
||||
- Git facultatif : le mode SAFE combine l'exécution hors dépôt avec un sandbox `workspace-write` limité au projet ;
|
||||
- debug Django/FastAPI et rechargement automatique désactivés ; secrets exclus de Git.
|
||||
- connecteur distant limité à un dossier, aux fichiers texte de 2 Mo et aux opérations liste/lecture/écriture ; jeton révocable et aucun terminal distant.
|
||||
- bridge IA limité aux adresses privées, associé par code temporaire et protégé
|
||||
par un jeton aléatoire chiffré au repos ; le proxy PC n’accepte que les routes
|
||||
Ollama nécessaires à la découverte et à l’inférence, avec une taille de requête
|
||||
bornée, et Ollama reste lié à localhost ; la configuration OpenCode générée et
|
||||
son jeton restent sous `data/local-ai/` en mode privé ;
|
||||
- règles communes versionnées et consignes projet injectées comme contexte, sans jamais remplacer les contrôles d’autorisation du backend ;
|
||||
- agent maître isolé derrière un socket Unix et un jeton local `0600`, réservé aux administrateurs avec confirmation explicite des demandes privilégiées, désactivé tant que le propriétaire ne l’installe pas sur l’hôte ;
|
||||
- approbations d’orchestration attachées à une empreinte ou un commit précis, invalidées par toute modification ultérieure.
|
||||
- chantier autonome réservé au propriétaire et démarré par une mutation CSRF explicite ; projets cibles résolus côté serveur dans son périmètre, un seul chantier actif, verdict du maître structuré et relances de correction bornées ; un blocage peut créer au maximum trois missions `CodexPi (Self)` dans un fil persistant, mais seule une réponse structurée `fixed` et testée permet une reprise automatique, tandis que `needs_user`, une autorité absente, un secret ou une opération irréversible maintiennent le blocage ; l’agent Self ne peut ni écrire directement dans SQLite, ni forcer un statut, ni modifier l’ordre, la cible ou le risque ; une reprise peut préciser les prompts mais ne peut changer ni l’ordre, ni la cible, ni le risque ; les interdictions de suppression, de migration irréversible et de contournement de sécurité des étapes restent applicables à chaque transmission.
|
||||
- exécution hôte des conversations limitée au projet global Pi Doctor/Agent Raspberry Pi déjà confirmé en `FULL ACCESS` et au propriétaire initial ; socket Unix et jeton `0600`, historique et file d’attente persistés, autres projets maintenus dans le worker conteneurisé.
|
||||
- centre de coordination réservé au propriétaire initial et mutations protégées par CSRF ; une réponse à une décision reprend le fil mais n’élargit jamais ses permissions et ne vaut ni confirmation destructive implicite, ni fourniture d’un secret absent ;
|
||||
- incidents techniques enregistrés sans le prompt complet dans la notification ; la mission de réparation reçoit le contexte nécessaire dans un fil privé de `CodexPi (Self)`, refuse le rejeu aveugle et exige une décision humaine pour les secrets, changements d’autorité et opérations irréversibles ;
|
||||
- agents spécialisés créés en SAFE dans des ateliers séparés, projets sources fournis en lecture, appel par compétence explicite et profondeur de délégation limitée à deux ; un spécialiste ne peut ni s’accorder `FULL ACCESS`, ni déployer, ni devenir l’intégrateur du projet appelant ;
|
||||
- budgets de ressources non destructifs : les seuils et priorités ne concernent que l’admission des nouvelles tâches, tandis qu’un dépassement de durée produit une alerte sans tuer, suspendre ou préempter le processus actif ;
|
||||
- catégories Web Push filtrées par préférence utilisateur avant mise en file, abonnements privés au compte et liens de notification limités aux routes internes de l’application.
|
||||
- réconciliation de stockage en dry-run par défaut : bases ouvertes en lecture seule et absence, illisibilité ou schéma incomplet traités en mode fermé ; un `data/` symbolique n'est jamais parcouru ; symlinks et tous leurs parents sont refusés ; références de conversation (y compris parentes) et sessions actives sont exclues ; état vivant relu sous verrou avant déplacement et admissions SQLite bloquées par `BEGIN IMMEDIATE` pendant toute la fenêtre critique ; worktrees sales ou verrouillés protégés ; quarantaine et restauration exigent chacune une confirmation liée à leur plan ou reçu, sont sérialisées par `flock` et journalisées dans un fichier privé `0600` ; aucune purge automatique ni ouverture implicite des profils Chromium.
|
||||
|
||||
## Limite importante
|
||||
|
||||
Le conteneur API accède au socket Docker pour fournir les actions demandées. Ce socket est une capacité très privilégiée : seuls des utilisateurs CodexPi de confiance doivent pouvoir se connecter. En particulier, `FULL ACCESS` peut écrire hors du projet courant dans les chemins visibles du conteneur et avoir des conséquences sur l'hôte ; l'avertissement n'est pas cosmétique. Sauvegardez les projets et limitez les membres/ACL du tailnet.
|
||||
|
||||
L’auto-réparation de cet accès ne relâche pas l’isolation du conteneur : l’API reste non-root, sans capacités Linux et avec `no-new-privileges`. L’installateur génère les unités avec les UID/GID numériques du propriétaire du projet, sans dépendre de son nom. Un service hôte sous ce compte compare seulement le GID du socket au groupe supplémentaire du conteneur et recrée l’API en cas d’écart, après la fin des tâches actives.
|
||||
|
||||
L'audit et les procédures de révocation figurent dans [SECURITY_AUDIT.md](SECURITY_AUDIT.md).
|
||||
Reference in New Issue
Block a user