diff --git a/.opencode/agents/lardon-architect.md b/.opencode/agents/lardon-architect.md new file mode 100644 index 0000000..02b1607 --- /dev/null +++ b/.opencode/agents/lardon-architect.md @@ -0,0 +1,14 @@ +--- +description: Analyse en lecture seule l'architecture et les invariants Lardon3D +mode: subagent +model: opencode/nemotron-3-ultra-free +temperature: 0.1 +permission: + edit: deny + bash: deny + task: deny +--- + +Analyse uniquement. Vérifie les frontières TUI, métier, scheduler et gouverneur, +les propriétés, durées de vie et invariants documentés. Ne modifie aucun fichier +et rends au parent un rapport concis, avec les défauts bloquants en premier. diff --git a/.opencode/agents/lardon-build.md b/.opencode/agents/lardon-build.md new file mode 100644 index 0000000..ba772ef --- /dev/null +++ b/.opencode/agents/lardon-build.md @@ -0,0 +1,26 @@ +--- +description: Agent principal C17 qui orchestre et implémente les tickets Lardon3D +mode: primary +model: opencode/deepseek-v4-flash-free +temperature: 0.1 +permission: + edit: + "*": allow + "scan3d/**": deny + task: + "*": deny + "lardon-architect": allow + "lardon-explore": allow + "lardon-review": allow + "lardon-concurrency": allow + "lardon-tests": allow + "lardon-docs": allow +--- + +Orchestre le ticket avec le minimum de sous-agents pertinents. Un seul agent +modifie les sources à un instant donné : toi. Lis les instructions projet déjà +chargées, préserve les changements existants et fournis aux sous-agents un +périmètre précis. Leurs rapports doivent rester concis. N'imbrique jamais de +sous-agent. Si DeepSeek retourne une saturation 503, demande à l'utilisateur de +relancer avec `opencode/nemotron-3-ultra-free`; ne sélectionne jamais un modèle +payant. diff --git a/.opencode/agents/lardon-concurrency.md b/.opencode/agents/lardon-concurrency.md new file mode 100644 index 0000000..1b32d40 --- /dev/null +++ b/.opencode/agents/lardon-concurrency.md @@ -0,0 +1,18 @@ +--- +description: Audit pthread spécialisé des fondations concurrentes +mode: subagent +model: opencode/nemotron-3-ultra-free +temperature: 0.1 +permission: + edit: deny + bash: + "*": deny + "git diff*": allow + "rg *": allow + task: deny +--- + +Audite pthread, mutex, conditions, transitions d'état, réveils perdus, +deadlocks, doubles libérations et data races. Cet audit est obligatoire pour +task, task_queue et resource_governor. Ne modifie rien et rapporte les scénarios +précis au parent. diff --git a/.opencode/agents/lardon-docs.md b/.opencode/agents/lardon-docs.md new file mode 100644 index 0000000..83a0173 --- /dev/null +++ b/.opencode/agents/lardon-docs.md @@ -0,0 +1,17 @@ +--- +description: Rédige uniquement la documentation Lardon3D +mode: subagent +model: opencode/ling-3.0-flash-free +temperature: 0.1 +permission: + edit: + "*": deny + "README.md": allow + "AGENTS.md": allow + "docs/**": allow + bash: deny + task: deny +--- + +Modifie uniquement README.md, AGENTS.md et docs/. Synthétise les documents +chargés sans les dupliquer et ne change jamais le code ou la configuration. diff --git a/.opencode/agents/lardon-explore.md b/.opencode/agents/lardon-explore.md new file mode 100644 index 0000000..ecd3398 --- /dev/null +++ b/.opencode/agents/lardon-explore.md @@ -0,0 +1,17 @@ +--- +description: Explore rapidement fichiers, symboles, appels et dépendances +mode: subagent +model: opencode/north-mini-code-free +temperature: 0.1 +permission: + edit: deny + bash: + "*": deny + "rg *": allow + "git grep*": allow + task: deny +--- + +Travaille en lecture seule. Localise exactement les fichiers, symboles, +appelants et dépendances demandés. Ne propose pas de réécriture et retourne des +chemins et conclusions synthétiques au parent. diff --git a/.opencode/agents/lardon-review.md b/.opencode/agents/lardon-review.md new file mode 100644 index 0000000..9c2fabe --- /dev/null +++ b/.opencode/agents/lardon-review.md @@ -0,0 +1,17 @@ +--- +description: Revue indépendante C17 des diffs, API et durées de vie +mode: subagent +model: opencode/laguna-s-2.1-free +temperature: 0.1 +permission: + edit: deny + bash: + "*": deny + "git diff*": allow + "git status*": allow + task: deny +--- + +Relis le diff sans le modifier. Vérifie C17, erreurs, nettoyage, overflows, +contrats d'API, ownership et conformité à AGENTS.md. Distingue bloquants, +importants et améliorations, puis rends un rapport court. diff --git a/.opencode/agents/lardon-tests.md b/.opencode/agents/lardon-tests.md new file mode 100644 index 0000000..47d5ad9 --- /dev/null +++ b/.opencode/agents/lardon-tests.md @@ -0,0 +1,22 @@ +--- +description: Exécute les validations Lardon3D sans modifier le code +mode: subagent +model: opencode/north-mini-code-free +temperature: 0.1 +permission: + edit: deny + bash: + "*": deny + "CC=clang meson setup *": allow + "meson compile *": allow + "meson test *": allow + "ninja *": allow + "git diff --check*": allow + "git status*": allow + task: deny +--- + +Exécute les commandes demandées et rapporte leurs sorties réelles. Utilise le +build normal, ASan/UBSan et TSan selon le risque. Ne modifie jamais le code sauf +instruction explicite du prompt principal, auquel cas refuse et renvoie la +correction au seul agent implémenteur. diff --git a/.opencode/commands/lardon-handoff.md b/.opencode/commands/lardon-handoff.md new file mode 100644 index 0000000..f8b05dd --- /dev/null +++ b/.opencode/commands/lardon-handoff.md @@ -0,0 +1,10 @@ +--- +description: Produire un compte rendu de transmission sans modifier le dépôt +agent: lardon-build +subtask: false +--- + +Sans modifier le code ni la documentation, produis un compte rendu autonome +pour une autre session ou un autre modèle : objectif, architecture pertinente, +état Git, travail réalisé, validations réellement exécutées, défauts et limites, +fichiers concernés et prochaine action sûre. diff --git a/.opencode/commands/lardon-review.md b/.opencode/commands/lardon-review.md new file mode 100644 index 0000000..bbf5d93 --- /dev/null +++ b/.opencode/commands/lardon-review.md @@ -0,0 +1,9 @@ +--- +description: Lancer une revue indépendante sans modification +agent: lardon-build +subtask: false +--- + +Sans modifier aucun fichier, lance lardon-review et lardon-concurrency comme +sous-tâches indépendantes sur le diff courant. Agrège leurs rapports en +distinguant défauts bloquants, risques et limites. Ne lance aucun autre agent. diff --git a/.opencode/commands/lardon-ticket.md b/.opencode/commands/lardon-ticket.md new file mode 100644 index 0000000..6325461 --- /dev/null +++ b/.opencode/commands/lardon-ticket.md @@ -0,0 +1,14 @@ +--- +description: Traiter un ticket Lardon3D avec exploration, architecture, tests et revue +agent: lardon-build +subtask: false +--- + +Traite ce ticket : $ARGUMENTS + +Lis les instructions déjà chargées, inspecte Git et les fichiers concernés. +Utilise lardon-explore puis lardon-architect seulement si pertinents. Après leur +rapport, implémente seul et minimalement. Délègue la validation à lardon-tests, +puis la revue finale à lardon-review et obligatoirement à lardon-concurrency si +task, task_queue, resource_governor ou pthread sont touchés. Aucun sous-agent +imbriqué, commit, push ou ajout de scan3d/. diff --git a/.opencode/commands/lardon-validate.md b/.opencode/commands/lardon-validate.md new file mode 100644 index 0000000..bbb083b --- /dev/null +++ b/.opencode/commands/lardon-validate.md @@ -0,0 +1,9 @@ +--- +description: Compiler et valider Lardon3D avec les sanitizers pertinents +agent: lardon-tests +subtask: true +--- + +Valide le ticket courant : compilation propre avec Clang, tests Meson et +`git diff --check`. Ajoute ASan/UBSan pour les durées de vie et TSan pour la +concurrence. Ne modifie aucun fichier et rapporte précisément chaque résultat. diff --git a/.opencode/opencode.json b/.opencode/opencode.json new file mode 100644 index 0000000..6c6d946 --- /dev/null +++ b/.opencode/opencode.json @@ -0,0 +1,46 @@ +{ + "$schema": "https://opencode.ai/config.json", + "default_agent": "lardon-build", + "model": "opencode/deepseek-v4-flash-free", + "subagent_depth": 1, + "instructions": [ + "AGENTS.md", + "docs/architecture/overview.md", + "docs/architecture/resource_governor.md", + "docs/architecture/scheduler_resource_integration.md", + "docs/architecture/foundation_review.md", + "docs/opencode_handoff.md" + ], + "permission": { + "*": "ask", + "read": "allow", + "glob": "allow", + "grep": "allow", + "lsp": "allow", + "external_directory": "deny", + "edit": { + "*": "allow", + "scan3d/**": "deny" + }, + "bash": { + "*": "ask", + "git status*": "allow", + "git diff*": "allow", + "git log*": "allow", + "git commit*": "deny", + "git push*": "deny", + "git add -A*": "deny", + "git clean*": "deny", + "git reset*": "deny", + "rm *": "deny", + "sudo *": "deny" + } + }, + "watcher": { + "ignore": [ + ".git/**", + "build*/**", + "scan3d/**" + ] + } +} diff --git a/docs/opencode_handoff.md b/docs/opencode_handoff.md new file mode 100644 index 0000000..4156352 --- /dev/null +++ b/docs/opencode_handoff.md @@ -0,0 +1,212 @@ +# Transmission du développement à OpenCode + +## 1. Vision du projet + +Lardon3D doit devenir un moteur complet de photogrammétrie Linux, piloté depuis +une TUI ncursesw. Le terminal reste le centre de contrôle pendant les calculs, +y compris ceux qui dureront plusieurs heures. La priorité est la robustesse : +maîtrise de la mémoire, reprise après interruption, résultats atomiques et +réactivité permanente du système hôte. + +Le logiciel traite les données par petits lots : lecture, calcul, validation et +écriture, puis libération avant le lot suivant. Il préfère une progression plus +lente mais bornée à une opération monolithique susceptible de saturer la RAM, +le GPU intégré ou les entrées-sorties. + +Lardon3D n'est pas un frontend OpenMVS. Son architecture, son modèle de projet, +son ordonnanceur, son gouverneur de ressources, ses formats de résultats et sa +reprise doivent lui appartenir. Un moteur externe éventuel serait un outil +encapsulé par une étape, jamais le propriétaire du pipeline ni de l'état. + +## 2. Architecture actuelle + +```text +TUI + ↓ +Task + ↓ +Estimate + ↓ +Governor + ↓ +Reservation + ↓ +Scheduler + ↓ +Worker +``` + +La TUI gère ncurses, les entrées, les écrans et les snapshots destinés au +layout. Le layout dessine uniquement. Les modules métier ne dépendent pas de +ncurses et aucun worker ne l'appelle. + +`Task` fournit état, progression, pause, reprise, annulation coopérative et +callback. Chaque tâche possède une `Lardon3DResourceEstimate` immuable. Le +profil matériel décrit les capacités stables ; un `ResourceSnapshot` mesure la +disponibilité dynamique. Le `ResourceGovernor` est l'unique arbitre des budgets +RAM, GPU, CPU et IO. Il répond `START`, `WAIT`, `REDUCE_BATCH` ou `REJECT` et +crée atomiquement une réservation opaque pour toute admission. + +La `TaskQueue` actuelle est FIFO avec un worker. Elle demande une réservation +juste avant l'exécution, transmet une copie du contrat au callback et libère la +réservation après succès, échec ou annulation. En `WAIT`, elle dort sur une +condition variable jusqu'à notification. Une tâche en pause conserve son +contrat dans cette version. + +## 3. Invariants + +- Aucun callback de tâche sans estimation et réservation active validée. +- Le gouverneur décide des ressources ; le scheduler exécute le contrat sans le + réinterpréter. +- Aucune variable globale d'état ni singleton. +- ncurses appartient exclusivement au thread principal. +- TUI, dessin et logique métier restent séparés. +- Les objets aux durées de vie complexes sont opaques et nettoyés explicitement. +- Une réservation est libérée exactement une fois ; la double libération est + refusée sans modifier les budgets. +- Les budgets et calculs de lots contrôlent les dépassements d'entiers. +- Les sorties structurantes sont atomiques ; un rollback ne retire que ce que + l'opération courante vient de créer. +- Les fichiers utilisateur antérieurs ne sont jamais écrasés silencieusement. +- La stabilité du système et la réactivité de la TUI priment sur le débit. +- Aucun traitement lourd monolithique : préférer des séquences et lots bornés. +- La mémoire d'un iGPU partagé est comptée dans le budget RAM système. +- Le swap et la zram sont des filets de sécurité, pas de la mémoire de travail. +- Une interruption doit préserver le dernier état validé et permettre la + reprise à une frontière connue. +- Le viewer futur reste séparé, non bloquant et lecteur de snapshots validés. + +## 4. État actuel + +### Terminé + +- TUI modulaire avec écrans Accueil, Projets, Import, Viewer, Aide, Tâches et + Ressources. +- État applicatif central, projets persistants et configuration de leur racine. +- Import sûr, asynchrone et annulable vers `images/originals`, avec manifeste + TSV atomique et rollback cohérent. +- Catalogue vérifié, navigation, tri et filtre en mémoire. +- Moteur générique de tâches et file FIFO à un worker. +- Détection du profil matériel et capture des snapshots Linux. +- Gouverneur thread-safe, estimations, lots adaptatifs et réservations opaques. +- Intégration scheduler/gouverneur avec réservation obligatoire avant callback. +- Tests normaux, ASan/UBSan et TSan des fondations. + +### En cours + +- Consolidation de la documentation et transfert vers OpenCode. +- Les contrats de lot existent, mais leur enchaînement en séquences complètes + n'est pas encore orchestré. + +### Non commencé + +- Étapes de photogrammétrie, pipeline et cache de calcul. +- DAG, dépendances, priorités et scheduler multi-worker. +- Persistance des tâches et checkpoints après crash. +- Migration de l'import vers le scheduler générique. +- Publication live des résultats et viewer Vulkan. + +## 5. Dette technique + +- Le FIFO strict bloque toute la file lorsqu'une tâche en tête reçoit `WAIT`. +- La file possède un seul worker. +- Une libération externe exige un appel explicite à + `lardon3d_task_queue_resources_changed()`. +- Les tombstones des réservations libérées restent alloués jusqu'à la + destruction du gouverneur. +- Une erreur de capture des ressources échoue la tâche sans distinguer une + panne transitoire. +- La destruction concurrente du gouverneur ou de la file avec leurs API actives + n'est pas supportée ; la file doit être détruite avant le gouverneur. +- Les files ne possèdent pas encore de capacité maximale ni de contre-pression. +- Les tâches et checkpoints ne survivent pas au processus. +- L'import conserve son système de thread spécialisé. +- `meson.build` référence deux fois `resource_snapshot.c` et + `resource_governor.c` dans la cible principale ; Meson le tolère, mais cette + duplication déclarative devra être nettoyée séparément. + +## 6. Ordre recommandé + +1. Sélectionner une tâche admissible sans blocage par la tête de file, afin que + `WAIT` n'immobilise pas des travaux compatibles avec les budgets restants. +2. Définir résultats atomiques, identifiants, métadonnées de validation et + frontières de reprise avant de produire des calculs coûteux. +3. Ajouter le DAG et les dépendances pour représenter explicitement le pipeline. +4. Persister tâches et checkpoints afin de rendre la reprise réelle. +5. Orchestrer des séquences adaptatives mesurées, une réservation par lot. +6. Borner les files, ajouter la contre-pression, puis introduire les pools CPU, + IO et GPU sans déplacer l'arbitrage hors du gouverneur. +7. Migrer l'import vers cette infrastructure validée. +8. Publier des snapshots live atomiques avant de commencer le viewer Vulkan. + +Cet ordre évite de paralléliser ou visualiser des résultats dont le cycle de +vie, la validation et la reprise ne seraient pas encore définis. + +## 7. Optimisations futures + +Les éléments suivants sont prévus mais ne sont pas implémentés : DAG de +dépendances, scheduler sélectionnant intelligemment les tâches admissibles, +séquences et lots adaptatifs, apprentissage des tailles de lots à partir des +mesures, pipeline photogrammétrique, cache, reprise après crash, publication +live et viewer Vulkan. Le viewer devra être séparé de la TUI, s'afficher sur le +workspace 8 et consommer uniquement des snapshots validés. + +Aucune de ces évolutions ne doit contourner les estimations et réservations ni +introduire des files ou allocations non bornées. + +## 8. Profil matériel cible + +Lardon3D détecte la machine au démarrage et observe ensuite ses ressources. Il +ne doit contenir aucune constante de dimensionnement propre à un processeur, un +volume de RAM ou un GPU particulier. Les valeurs matérielles connues servent à +établir des plafonds ; les snapshots dynamiques et réservations déterminent ce +qui peut réellement démarrer. + +L'optimisation CPU, RAM, GPU et IO vise une utilisation soutenue mais sûre. Une +marge reste disponible pour Linux, la TUI et les autres applications. Les iGPU +partagent la RAM et doivent être comptabilisés comme tels. Le swap et la zram +signalent une pression dangereuse, jamais une capacité normale supplémentaire. + +## 9. Principes d'évolution + +- Lire `AGENTS.md` et toute la documentation d'architecture avant de modifier + les fondations. +- Étendre les abstractions validées au lieu de les réécrire. +- Ne jamais contourner le gouverneur ni fabriquer un contrat d'exécution. +- Maintenir la propriété explicite des tâches, réservations, threads, mutex, + conditions, descripteurs et allocations. +- Préférer plusieurs petits lots validés à une grande opération. +- Borner mémoire, files, parallélisme et IO avant toute optimisation de débit. +- Préserver l'annulation coopérative, les rollbacks ciblés et les écritures + atomiques. +- Ajouter les tests de durée de vie et concurrence avec chaque évolution. +- Valider avec Clang, Meson, tests, `git diff --check`, ASan/UBSan et TSan selon + le risque. +- Ne jamais modifier ni ajouter `scan3d/` ou `scan3d/tri_photos.py`. + +## 10. Prompt OpenCode + +```text +Tu reprends le développement de Lardon3D, un moteur complet de photogrammétrie +Linux en C17 piloté par une TUI ncursesw. + +Avant toute modification : +- lis README.md, AGENTS.md, docs/opencode_handoff.md et tous les documents de + docs/architecture/ ; +- inspecte entièrement le dépôt, l'état Git, les headers publics, les sources, + les tests et meson.build ; +- comprends les propriétés, durées de vie et frontières de threads existantes ; +- préserve les changements utilisateur et ne touche jamais à scan3d/. + +Respecte impérativement tous les invariants documentés : séparation TUI/métier/ +layout, ncurses uniquement sur le thread principal, estimations immuables, +gouverneur seul arbitre des ressources, réservation active avant tout callback, +budgets et files bornés, traitement par petits lots, sorties atomiques, +rollback ciblé, reprise et stabilité du système prioritaire. + +Ne réécris pas les fondations validées et ne contourne jamais le gouverneur. +Poursuis les développements dans l'ordre recommandé par ce document, un ticket +à la fois, sans ajouter prématurément DAG, pools, photogrammétrie ou Vulkan. +Exécute les validations prescrites par AGENTS.md et rapporte honnêtement leurs +résultats ainsi que la liste exacte des fichiers du ticket. +``` diff --git a/docs/opencode_models.md b/docs/opencode_models.md new file mode 100644 index 0000000..09a7a9e --- /dev/null +++ b/docs/opencode_models.md @@ -0,0 +1,75 @@ +# Inventaire des modèles OpenCode + +Inventaire effectué le 6 août 2026 avec +`opencode models --refresh --verbose`. Le seul fournisseur connecté exposé est +`opencode` via OpenCode Zen. Aucun modèle local n'est apparu. Les catégories +ci-dessous reposent sur le nom explicite et les champs `cost` retournés par le +CLI, pas sur une supposition liée à la famille du modèle. + +## Modèles gratuits détectés + +Sept modèles sont explicitement nommés « Free » et annoncent un coût nul en +entrée, sortie et cache : + +- `opencode/deepseek-v4-flash-free` : agent principal `lardon-build` ; repli + recommandé `opencode/nemotron-3-ultra-free` en cas de saturation 503. +- `opencode/nemotron-3-ultra-free` : architecture et concurrence ; repli de + l'agent principal. +- `opencode/north-mini-code-free` : exploration rapide et validations. +- `opencode/laguna-s-2.1-free` : revue indépendante ; repli économique pour les + analyses générales. +- `opencode/ling-3.0-flash-free` : documentation. +- `opencode/longcat-2.0-free` : disponible, non configuré actuellement. +- `opencode/mimo-v2.5-free` : disponible, non configuré actuellement. + +## Gratuité non confirmée + +`opencode/big-pickle` annonce un coût nul dans les métadonnées du CLI, mais son +nom ne le qualifie pas explicitement de gratuit. Il reste volontairement non +configuré tant que les conditions de son offre ne sont pas confirmées. + +## Modèles payants volontairement exclus + +Les modèles suivants annoncent un coût non nul et ne sont référencés par aucun +agent ni par la configuration principale : + +- Claude : `claude-fable-5`, `claude-haiku-4-5`, `claude-opus-4-1`, + `claude-opus-4-5`, `claude-opus-4-6`, `claude-opus-4-7`, + `claude-opus-4-8`, `claude-opus-5`, `claude-sonnet-4`, + `claude-sonnet-4-5`, `claude-sonnet-4-6`, `claude-sonnet-5`. +- DeepSeek : `deepseek-v4-flash`, `deepseek-v4-pro`. +- Gemini : `gemini-3-flash`, `gemini-3.1-pro`, `gemini-3.5-flash`, + `gemini-3.5-flash-lite`, `gemini-3.6-flash`. +- GLM : `glm-5`, `glm-5.1`, `glm-5.2`. +- GPT : `gpt-5`, `gpt-5-codex`, `gpt-5-nano`, `gpt-5.1`, + `gpt-5.1-codex`, `gpt-5.1-codex-max`, `gpt-5.1-codex-mini`, + `gpt-5.2`, `gpt-5.2-codex`, `gpt-5.3-codex`, + `gpt-5.3-codex-spark`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.4-nano`, + `gpt-5.4-pro`, `gpt-5.5`, `gpt-5.5-pro`, `gpt-5.6-luna`, + `gpt-5.6-sol`, `gpt-5.6-terra`. +- Grok : `grok-4.5`, `grok-build-0.1`. +- Kimi : `kimi-k2.5`, `kimi-k2.6`, `kimi-k2.7-code`, `kimi-k3`. +- MiniMax : `minimax-m2.5`, `minimax-m2.7`, `minimax-m3`. +- Qwen : `qwen3.5-plus`, `qwen3.6-plus`. + +Tous ces identifiants ont le préfixe fournisseur `opencode/`. Aucun basculement +automatique vers eux n'est autorisé. Si tous les modèles gratuits adaptés sont +indisponibles, interrompre le travail plutôt que choisir un modèle payant. + +## Modèles locaux + +Aucun fournisseur ni modèle local n'a été détecté dans la configuration +OpenCode actuelle. + +## Actualisation + +Les offres changent. Réexécuter : + +```sh +opencode models --refresh --verbose +``` + +Comparer les identifiants, le fournisseur et surtout les champs `cost`. Ne pas +déduire la gratuité du nom seul. Mettre ensuite à jour ce document et chaque +frontmatter `model:` sous `.opencode/agents/`, puis valider la configuration +avec `opencode debug config`.