feat: skip resource-blocked tasks in scheduler
This commit is contained in:
parent
983b435d3c
commit
cc9c29cb74
27 changed files with 496 additions and 112 deletions
5
.opencode/.gitignore
vendored
Normal file
5
.opencode/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
node_modules
|
||||||
|
package.json
|
||||||
|
package-lock.json
|
||||||
|
bun.lock
|
||||||
|
work/
|
||||||
|
|
@ -9,6 +9,7 @@ permission:
|
||||||
task: deny
|
task: deny
|
||||||
---
|
---
|
||||||
|
|
||||||
Analyse uniquement. Vérifie les frontières TUI, métier, scheduler et gouverneur,
|
Interviens uniquement pour une API publique, le scheduler, le gouverneur, le
|
||||||
|
DAG, la persistance ou une concurrence importante. Vérifie les frontières,
|
||||||
les propriétés, durées de vie et invariants documentés. Ne modifie aucun fichier
|
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.
|
et rends au parent seulement conclusions, risques, fichiers et décisions.
|
||||||
|
|
|
||||||
16
.opencode/agents/lardon-build-backup.md
Normal file
16
.opencode/agents/lardon-build-backup.md
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
description: Reprend les tickets complexes interrompus sans refaire l'analyse
|
||||||
|
mode: subagent
|
||||||
|
model: opencode/nemotron-3-ultra-free
|
||||||
|
temperature: 0.1
|
||||||
|
permission:
|
||||||
|
edit:
|
||||||
|
"*": allow
|
||||||
|
"scan3d/**": deny
|
||||||
|
task: deny
|
||||||
|
---
|
||||||
|
|
||||||
|
Lis d'abord `.opencode/work/current_ticket.md`, le diff et les seuls fichiers
|
||||||
|
concernés. Reprends le working tree existant à la prochaine action sûre sans
|
||||||
|
refaire l'analyse si le handoff suffit. Implémente minimalement, sans sous-agent,
|
||||||
|
commit, push ni modèle payant. Mets à jour le handoff avec un résumé concis.
|
||||||
17
.opencode/agents/lardon-build-light.md
Normal file
17
.opencode/agents/lardon-build-light.md
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
description: Traite les petits tickets et corrections locales à faible coût
|
||||||
|
mode: subagent
|
||||||
|
model: opencode/mimo-v2.5-free
|
||||||
|
temperature: 0.1
|
||||||
|
permission:
|
||||||
|
edit:
|
||||||
|
"*": allow
|
||||||
|
"scan3d/**": deny
|
||||||
|
task: deny
|
||||||
|
---
|
||||||
|
|
||||||
|
Traite seulement les petits changements locaux, tests simples, nettoyage ou
|
||||||
|
documentation demandée. Lis le handoff et les fichiers ciblés, sans sous-agent.
|
||||||
|
Si le ticket touche une fondation sensible, une API complexe ou exige un gros
|
||||||
|
refactoring, arrête-toi et signale qu'il faut Nemotron, DeepSeek ou Codex. Ne
|
||||||
|
réécris jamais une fondation pour contourner cette limite.
|
||||||
|
|
@ -1,26 +1,18 @@
|
||||||
---
|
---
|
||||||
description: Agent principal C17 qui orchestre et implémente les tickets Lardon3D
|
description: Implémente seul les tickets complexes Lardon3D
|
||||||
mode: primary
|
mode: subagent
|
||||||
model: opencode/deepseek-v4-flash-free
|
model: opencode/deepseek-v4-flash-free
|
||||||
temperature: 0.1
|
temperature: 0.1
|
||||||
permission:
|
permission:
|
||||||
edit:
|
edit:
|
||||||
"*": allow
|
"*": allow
|
||||||
"scan3d/**": deny
|
"scan3d/**": deny
|
||||||
task:
|
task: deny
|
||||||
"*": 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
|
Implémente uniquement le plan concis transmis par l'orchestrateur. Lis le
|
||||||
modifie les sources à un instant donné : toi. Lis les instructions projet déjà
|
handoff et seulement les fichiers et documents indiqués. Ne refais pas
|
||||||
chargées, préserve les changements existants et fournis aux sous-agents un
|
l'exploration, ne lance aucun sous-agent et préserve le working tree existant.
|
||||||
périmètre précis. Leurs rapports doivent rester concis. N'imbrique jamais de
|
Tu es l'unique auteur des sources pendant ta phase. Mets à jour le handoff avec
|
||||||
sous-agent. Si DeepSeek retourne une saturation 503, demande à l'utilisateur de
|
les changements et erreurs utiles, sans longs logs. Aucun commit, push ou
|
||||||
relancer avec `opencode/nemotron-3-ultra-free`; ne sélectionne jamais un modèle
|
modèle payant.
|
||||||
payant.
|
|
||||||
|
|
|
||||||
|
|
@ -14,5 +14,5 @@ permission:
|
||||||
|
|
||||||
Audite pthread, mutex, conditions, transitions d'état, réveils perdus,
|
Audite pthread, mutex, conditions, transitions d'état, réveils perdus,
|
||||||
deadlocks, doubles libérations et data races. Cet audit est obligatoire pour
|
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
|
task, task_queue et resource_governor, mais inutile hors code concurrent. Ne
|
||||||
précis au parent.
|
modifie rien et rapporte uniquement les scénarios précis et leur gravité.
|
||||||
|
|
|
||||||
|
|
@ -13,5 +13,6 @@ permission:
|
||||||
task: deny
|
task: deny
|
||||||
---
|
---
|
||||||
|
|
||||||
Modifie uniquement README.md, AGENTS.md et docs/. Synthétise les documents
|
Modifie uniquement README.md, AGENTS.md et docs/ lorsqu'un ticket le demande
|
||||||
chargés sans les dupliquer et ne change jamais le code ou la configuration.
|
explicitement. Charge seulement les documents pertinents, synthétise sans les
|
||||||
|
dupliquer et ne change jamais le code ou la configuration.
|
||||||
|
|
|
||||||
|
|
@ -13,5 +13,6 @@ permission:
|
||||||
---
|
---
|
||||||
|
|
||||||
Travaille en lecture seule. Localise exactement les fichiers, symboles,
|
Travaille en lecture seule. Localise exactement les fichiers, symboles,
|
||||||
appelants et dépendances demandés. Ne propose pas de réécriture et retourne des
|
appelants, dépendances et documents strictement utiles. Ne lis pas toute
|
||||||
chemins et conclusions synthétiques au parent.
|
l'architecture par défaut, ne propose pas de réécriture et retourne uniquement
|
||||||
|
les chemins, conclusions et risques synthétiques.
|
||||||
|
|
|
||||||
32
.opencode/agents/lardon-orchestrator.md
Normal file
32
.opencode/agents/lardon-orchestrator.md
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
---
|
||||||
|
description: Orchestre les tickets avec un contexte minimal et sans écrire les sources
|
||||||
|
mode: primary
|
||||||
|
model: opencode/north-mini-code-free
|
||||||
|
temperature: 0.1
|
||||||
|
permission:
|
||||||
|
edit:
|
||||||
|
"*": deny
|
||||||
|
".opencode/work/current_ticket.md": allow
|
||||||
|
bash:
|
||||||
|
"*": deny
|
||||||
|
"git status*": allow
|
||||||
|
"git diff*": allow
|
||||||
|
"codex --help*": allow
|
||||||
|
task:
|
||||||
|
"*": deny
|
||||||
|
"lardon-build": allow
|
||||||
|
"lardon-build-backup": allow
|
||||||
|
"lardon-build-light": allow
|
||||||
|
"lardon-architect": allow
|
||||||
|
"lardon-explore": allow
|
||||||
|
"lardon-review": allow
|
||||||
|
"lardon-concurrency": allow
|
||||||
|
"lardon-tests": allow
|
||||||
|
"lardon-docs": allow
|
||||||
|
---
|
||||||
|
|
||||||
|
Orchestre sans modifier les sources. Charge AGENTS.md et l'overview déjà
|
||||||
|
injectés, puis utilise explore pour cibler le contexte. N'appelle que les agents
|
||||||
|
pertinents, sans sous-agent imbriqué. Transmets au seul implémenteur un résumé
|
||||||
|
court : objectif, contraintes, fichiers, API, invariants et tests. Tiens le
|
||||||
|
handoff concis à jour après chaque phase. Aucun modèle payant, commit ou push.
|
||||||
|
|
@ -14,4 +14,4 @@ permission:
|
||||||
|
|
||||||
Relis le diff sans le modifier. Vérifie C17, erreurs, nettoyage, overflows,
|
Relis le diff sans le modifier. Vérifie C17, erreurs, nettoyage, overflows,
|
||||||
contrats d'API, ownership et conformité à AGENTS.md. Distingue bloquants,
|
contrats d'API, ownership et conformité à AGENTS.md. Distingue bloquants,
|
||||||
importants et améliorations, puis rends un rapport court.
|
importants et limites. Ne répète pas les tests réussis et rends un rapport court.
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,6 @@ permission:
|
||||||
---
|
---
|
||||||
|
|
||||||
Exécute les commandes demandées et rapporte leurs sorties réelles. Utilise le
|
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
|
build normal, ASan/UBSan et TSan selon le risque. Ne modifie jamais le code : si
|
||||||
instruction explicite du prompt principal, auquel cas refuse et renvoie la
|
une correction est nécessaire, renvoie-la au seul agent implémenteur. Pour les
|
||||||
correction au seul agent implémenteur.
|
succès, rapporte seulement commande, statut et synthèse.
|
||||||
|
|
|
||||||
11
.opencode/commands/lardon-codex-handoff.md
Normal file
11
.opencode/commands/lardon-codex-handoff.md
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
description: Préparer une reprise courte dans Codex CLI
|
||||||
|
agent: lardon-orchestrator
|
||||||
|
subtask: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Mets le handoff à jour depuis le statut et le diff, sans modifier les sources.
|
||||||
|
Vérifie d'abord `codex --help`. Produis ensuite un prompt court copiable qui
|
||||||
|
demande à Codex de lire AGENTS.md, le handoff, le diff et seulement les fichiers
|
||||||
|
cités, puis de reprendre à la prochaine action sûre. Ne lance pas Codex, n'invente
|
||||||
|
aucune option, ne demande aucune clé et n'inclus aucun secret.
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
---
|
---
|
||||||
description: Produire un compte rendu de transmission sans modifier le dépôt
|
description: Produire un compte rendu de transmission sans modifier le dépôt
|
||||||
agent: lardon-build
|
agent: lardon-orchestrator
|
||||||
subtask: false
|
subtask: false
|
||||||
---
|
---
|
||||||
|
|
||||||
Sans modifier le code ni la documentation, produis un compte rendu autonome
|
Sans modifier le code ni la documentation suivie, lis le handoff, le statut Git
|
||||||
pour une autre session ou un autre modèle : objectif, architecture pertinente,
|
et le diff, puis produis un compte rendu autonome : objectif, contraintes,
|
||||||
état Git, travail réalisé, validations réellement exécutées, défauts et limites,
|
architecture strictement pertinente, travail réalisé, validations réelles,
|
||||||
fichiers concernés et prochaine action sûre.
|
défauts, fichiers et prochaine action sûre. N'inclus aucun long log ni secret.
|
||||||
|
|
|
||||||
14
.opencode/commands/lardon-plan.md
Normal file
14
.opencode/commands/lardon-plan.md
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
description: Planifier en lecture seule avec un contexte minimal
|
||||||
|
agent: lardon-orchestrator
|
||||||
|
subtask: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Planifie ce ticket sans modifier les sources : $ARGUMENTS
|
||||||
|
|
||||||
|
Lis AGENTS.md et l'overview déjà chargés. Demande à lardon-explore uniquement
|
||||||
|
les modules concernés. Liste les fichiers et documents à charger, propose un plan
|
||||||
|
court et indique les agents réellement nécessaires. Écris dans
|
||||||
|
`.opencode/work/current_ticket.md` : titre, objectif, contraintes, fichiers,
|
||||||
|
documents utiles, plan, travail terminé/restant, fichiers modifiés, commandes,
|
||||||
|
tests passés/restants, décisions, erreurs, modèle et prochaine action sûre.
|
||||||
10
.opencode/commands/lardon-resume-backup.md
Normal file
10
.opencode/commands/lardon-resume-backup.md
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
description: Reprise rapide du handoff avec Nemotron
|
||||||
|
agent: lardon-orchestrator
|
||||||
|
subtask: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Reprends le ticket avec lardon-build-backup. Lis uniquement le handoff, le diff
|
||||||
|
et les fichiers qu'ils citent. Ne refais ni exploration ni architecture si les
|
||||||
|
informations suffisent. Appelle concurrency uniquement si nécessaire, puis mets
|
||||||
|
le handoff à jour avec la prochaine action sûre.
|
||||||
10
.opencode/commands/lardon-resume-from-codex.md
Normal file
10
.opencode/commands/lardon-resume-from-codex.md
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
description: Reprendre dans OpenCode le working tree laissé par Codex
|
||||||
|
agent: lardon-orchestrator
|
||||||
|
subtask: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Lis le handoff et inspecte le diff laissé par Codex. Charge uniquement les
|
||||||
|
fichiers modifiés, sans refaire l'architecture. Lance lardon-review, puis
|
||||||
|
lardon-concurrency seulement si pertinent, puis lardon-tests. Mets le handoff à
|
||||||
|
jour avec les résultats et la prochaine action. Ne modifie pas les sources.
|
||||||
10
.opencode/commands/lardon-resume-light.md
Normal file
10
.opencode/commands/lardon-resume-light.md
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
description: Reprise limitée d'un petit ticket avec MiMo
|
||||||
|
agent: lardon-orchestrator
|
||||||
|
subtask: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Lis le handoff, le diff et les fichiers cités, puis confie uniquement un petit
|
||||||
|
travail local à lardon-build-light. Si le reste touche une fondation, une API ou
|
||||||
|
un refactoring sensible, ne modifie rien : conserve le handoff et recommande
|
||||||
|
DeepSeek, Nemotron ou Codex. Mets à jour la prochaine action sûre.
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
---
|
---
|
||||||
description: Lancer une revue indépendante sans modification
|
description: Lancer une revue indépendante sans modification
|
||||||
agent: lardon-build
|
agent: lardon-orchestrator
|
||||||
subtask: false
|
subtask: false
|
||||||
---
|
---
|
||||||
|
|
||||||
Sans modifier aucun fichier, lance lardon-review et lardon-concurrency comme
|
Sans modifier aucun fichier, lance lardon-review sur le diff courant. Lance
|
||||||
sous-tâches indépendantes sur le diff courant. Agrège leurs rapports en
|
lardon-concurrency en sous-tâche indépendante uniquement si le diff touche
|
||||||
distinguant défauts bloquants, risques et limites. Ne lance aucun autre agent.
|
pthread, task, task_queue ou resource_governor. Agrège seulement les défauts,
|
||||||
|
risques et limites. Ne lance aucun autre agent.
|
||||||
|
|
|
||||||
10
.opencode/commands/lardon-save-handoff.md
Normal file
10
.opencode/commands/lardon-save-handoff.md
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
description: Sauvegarder l'état courant du ticket sans modifier les sources
|
||||||
|
agent: lardon-orchestrator
|
||||||
|
subtask: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Sans sous-agent ni modification des sources, inspecte `git status`, le diff et
|
||||||
|
le handoff existant. Mets `.opencode/work/current_ticket.md` à jour avec les
|
||||||
|
rubriques prescrites. Résume les commandes et erreurs ; ne copie ni sources,
|
||||||
|
documentation, longs logs, secrets ou données utilisateur.
|
||||||
14
.opencode/commands/lardon-small.md
Normal file
14
.opencode/commands/lardon-small.md
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
description: Traiter un petit ticket avec MiMo et des validations ciblées
|
||||||
|
agent: lardon-orchestrator
|
||||||
|
subtask: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Traite ce petit ticket : $ARGUMENTS
|
||||||
|
|
||||||
|
Utilise lardon-explore pour cibler les fichiers, puis un seul lardon-build-light
|
||||||
|
pour modifier. N'appelle architect, concurrency ou docs que si leur besoin est
|
||||||
|
avéré ; si le ticket est sensible, arrête et recommande le workflow normal.
|
||||||
|
Appelle ensuite lardon-tests pour compilation, tests ciblés et
|
||||||
|
`git diff --check`, puis une revue seulement si le diff le justifie. Maintiens
|
||||||
|
le handoff concis. Aucun commit, push ou fallback payant.
|
||||||
11
.opencode/commands/lardon-ticket-backup.md
Normal file
11
.opencode/commands/lardon-ticket-backup.md
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
description: Reprendre un ticket gratuit avec Nemotron après indisponibilité DeepSeek
|
||||||
|
agent: lardon-orchestrator
|
||||||
|
subtask: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Lis d'abord `.opencode/work/current_ticket.md` et le diff. Si le handoff suffit,
|
||||||
|
ne refais pas l'exploration. Transmets seulement l'objectif, les fichiers, les
|
||||||
|
invariants, le travail restant et la prochaine action à lardon-build-backup.
|
||||||
|
Après reprise, appelle lardon-tests puis lardon-review ; concurrency uniquement
|
||||||
|
si pertinent. Mets à jour le handoff après chaque phase. Aucun modèle payant.
|
||||||
|
|
@ -1,14 +1,19 @@
|
||||||
---
|
---
|
||||||
description: Traiter un ticket Lardon3D avec exploration, architecture, tests et revue
|
description: Traiter un ticket gratuit avec contexte progressif et handoff
|
||||||
agent: lardon-build
|
agent: lardon-orchestrator
|
||||||
subtask: false
|
subtask: false
|
||||||
---
|
---
|
||||||
|
|
||||||
Traite ce ticket : $ARGUMENTS
|
Traite ce ticket : $ARGUMENTS
|
||||||
|
|
||||||
Lis les instructions déjà chargées, inspecte Git et les fichiers concernés.
|
1. Initialise `.opencode/work/current_ticket.md` avec les rubriques prescrites.
|
||||||
Utilise lardon-explore puis lardon-architect seulement si pertinents. Après leur
|
2. Demande à lardon-explore les seuls fichiers et documents utiles.
|
||||||
rapport, implémente seul et minimalement. Délègue la validation à lardon-tests,
|
3. Charge uniquement ce contexte. Appelle lardon-architect seulement pour une
|
||||||
puis la revue finale à lardon-review et obligatoirement à lardon-concurrency si
|
abstraction importante, puis transmets un résumé concis à lardon-build.
|
||||||
task, task_queue, resource_governor ou pthread sont touchés. Aucun sous-agent
|
4. Après l'implémentation, appelle lardon-tests une fois, puis lardon-review une
|
||||||
imbriqué, commit, push ou ajout de scan3d/.
|
fois. Ajoute lardon-concurrency uniquement pour du code concurrent.
|
||||||
|
5. Mets le handoff à jour après chaque phase avec conclusions, commandes,
|
||||||
|
erreurs et prochaine action, sans documentation, sources ou logs complets.
|
||||||
|
|
||||||
|
Un seul agent écrit les sources. Aucun sous-agent imbriqué, commit, push,
|
||||||
|
fallback payant ou modification de scan3d/.
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,11 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://opencode.ai/config.json",
|
"$schema": "https://opencode.ai/config.json",
|
||||||
"default_agent": "lardon-build",
|
"default_agent": "lardon-orchestrator",
|
||||||
"model": "opencode/deepseek-v4-flash-free",
|
"model": "opencode/north-mini-code-free",
|
||||||
"subagent_depth": 1,
|
"subagent_depth": 1,
|
||||||
"instructions": [
|
"instructions": [
|
||||||
"AGENTS.md",
|
"AGENTS.md",
|
||||||
"docs/architecture/overview.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": {
|
"permission": {
|
||||||
"*": "ask",
|
"*": "ask",
|
||||||
|
|
@ -20,7 +16,8 @@
|
||||||
"external_directory": "deny",
|
"external_directory": "deny",
|
||||||
"edit": {
|
"edit": {
|
||||||
"*": "allow",
|
"*": "allow",
|
||||||
"scan3d/**": "deny"
|
"scan3d/**": "deny",
|
||||||
|
"scan3d/tri_photos.py": "deny"
|
||||||
},
|
},
|
||||||
"bash": {
|
"bash": {
|
||||||
"*": "ask",
|
"*": "ask",
|
||||||
|
|
@ -40,6 +37,7 @@
|
||||||
"ignore": [
|
"ignore": [
|
||||||
".git/**",
|
".git/**",
|
||||||
"build*/**",
|
"build*/**",
|
||||||
|
".opencode/work/**",
|
||||||
"scan3d/**"
|
"scan3d/**"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,63 @@ indisponibles, interrompre le travail plutôt que choisir un modèle payant.
|
||||||
Aucun fournisseur ni modèle local n'a été détecté dans la configuration
|
Aucun fournisseur ni modèle local n'a été détecté dans la configuration
|
||||||
OpenCode actuelle.
|
OpenCode actuelle.
|
||||||
|
|
||||||
|
## Optimisation du quota
|
||||||
|
|
||||||
|
L'agent par défaut est `lardon-orchestrator` sur North Mini Code Free. Il charge
|
||||||
|
seulement `AGENTS.md` et l'overview, puis demande à North Mini Code une
|
||||||
|
exploration ciblée. DeepSeek est réservé à l'implémentation complexe ; il ne sert
|
||||||
|
ni à l'orchestration, ni aux tests, ni à la documentation. Nemotron traite les
|
||||||
|
reprises et analyses d'architecture ou de concurrence, MiMo les petits tickets,
|
||||||
|
Laguna la revue et Ling la documentation.
|
||||||
|
|
||||||
|
Les commandes `lardon-plan`, `lardon-small`, `lardon-ticket` et
|
||||||
|
`lardon-ticket-backup` chargent progressivement le contexte. Elles ne lisent pas
|
||||||
|
automatiquement toute l'architecture et transmettent uniquement objectif,
|
||||||
|
contraintes, fichiers, API, invariants, risques et tests. Les rapports de succès
|
||||||
|
restent courts. Le handoff ignoré `.opencode/work/current_ticket.md` permet une
|
||||||
|
reprise sans rejouer toute l'analyse.
|
||||||
|
|
||||||
|
## Chaîne de secours
|
||||||
|
|
||||||
|
La voie normale est DeepSeek V4 Flash Free pour l'implémentation. En cas de 503,
|
||||||
|
saturation, quota épuisé ou interruption, sauvegarder le handoff et reprendre
|
||||||
|
avec Nemotron 3 Ultra Free. Si Nemotron est indisponible, MiMo V2.5 Free est
|
||||||
|
limité aux petits changements ; il doit refuser une fondation sensible.
|
||||||
|
|
||||||
|
GPT-5.6 Sol n'est pas actif dans OpenCode, car l'identifiant visible passe par
|
||||||
|
Zen et annonce un tarif. Pour utiliser le quota ChatGPT/Codex, la voie normale
|
||||||
|
reste Codex CLI via `lardon-codex-handoff`, puis
|
||||||
|
`lardon-resume-from-codex`. Aucun modèle payant n'est un fallback.
|
||||||
|
|
||||||
|
## GPT-5.6 Sol dans OpenCode
|
||||||
|
|
||||||
|
Vérification locale du 6 août 2026 avec OpenCode 1.18.13 :
|
||||||
|
|
||||||
|
- identifiant exact : `opencode/gpt-5.6-sol` ;
|
||||||
|
- fournisseur : `opencode`, affiché comme OpenCode Zen ;
|
||||||
|
- endpoint déclaré : `https://opencode.ai/zen/v1` ;
|
||||||
|
- authentification active : credential Zen de type `api` ;
|
||||||
|
- clé OpenAI API séparée : non requise par cette route Zen, mais le credential
|
||||||
|
Zen reste nécessaire ;
|
||||||
|
- OAuth ChatGPT/Codex : non détecté ;
|
||||||
|
- plugin Codex OAuth : non installé ;
|
||||||
|
- OpenCode Zen utilisé : oui ;
|
||||||
|
- tarif affiché : entrée 5, sortie 30, cache lecture 0,5 et écriture 6,25 dans
|
||||||
|
les unités tarifaires retournées par OpenCode ; tarifs supérieurs au-delà du
|
||||||
|
palier de contexte indiqué ;
|
||||||
|
- facturation distincte du quota Codex : route Zen tarifée, donc à considérer
|
||||||
|
distincte ;
|
||||||
|
- quota Codex partagé : non confirmé et aucune preuve locale ne l'indique ;
|
||||||
|
- test minimal : non exécuté, car la route identifiée est payante ;
|
||||||
|
- classement : **Q3 — GPT-5.6 Sol fourni par OpenCode Zen** ;
|
||||||
|
- politique : aucun agent, commande active ou fallback Sol dans OpenCode.
|
||||||
|
|
||||||
|
La preuve locale combine `opencode models --refresh --verbose`, qui expose le
|
||||||
|
fournisseur, l'endpoint et le coût, et `opencode providers list`, qui expose un
|
||||||
|
seul credential OpenCode Zen. La configuration globale ne déclare aucun
|
||||||
|
fournisseur OpenAI ni plugin d'authentification Codex. Aucun secret n'a été lu
|
||||||
|
ou reproduit dans ce document.
|
||||||
|
|
||||||
## Actualisation
|
## Actualisation
|
||||||
|
|
||||||
Les offres changent. Réexécuter :
|
Les offres changent. Réexécuter :
|
||||||
|
|
|
||||||
76
docs/opencode_workflow.md
Normal file
76
docs/opencode_workflow.md
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
# Workflow OpenCode et Codex
|
||||||
|
|
||||||
|
Ce workflow minimise le contexte tout en conservant un handoff fiable. Le
|
||||||
|
fichier `.opencode/work/current_ticket.md` est local et ignoré par Git. Il ne
|
||||||
|
contient que l'objectif, les contraintes, fichiers et documents utiles, plan,
|
||||||
|
travail terminé et restant, fichiers modifiés, commandes, tests, décisions,
|
||||||
|
erreurs, modèle actif et prochaine action sûre.
|
||||||
|
|
||||||
|
## A. Ticket gratuit normal
|
||||||
|
|
||||||
|
Lancer `/lardon-plan`, puis `/lardon-ticket`. North orchestre et explore via des
|
||||||
|
agents distincts, puis DeepSeek implémente. Architect et concurrency ne sont appelés que si le
|
||||||
|
périmètre l'exige. Tests et revue interviennent une seule fois après le code.
|
||||||
|
|
||||||
|
## B. DeepSeek retourne 503
|
||||||
|
|
||||||
|
Lancer `/lardon-save-handoff`, puis `/lardon-resume-backup`. Nemotron lit le
|
||||||
|
handoff et le diff, reprend la prochaine action et ne refait pas l'analyse si
|
||||||
|
les informations suffisent.
|
||||||
|
|
||||||
|
## C. DeepSeek et Nemotron sont indisponibles
|
||||||
|
|
||||||
|
Lancer `/lardon-resume-light` uniquement si le travail restant est petit et
|
||||||
|
local. Pour une fondation sensible, conserver le handoff et attendre DeepSeek
|
||||||
|
ou Codex ; ne pas forcer MiMo à réécrire l'architecture.
|
||||||
|
|
||||||
|
## D. Petit ticket avec MiMo
|
||||||
|
|
||||||
|
Lancer `/lardon-small`. L'exploration reste ciblée, MiMo est le seul auteur,
|
||||||
|
puis les validations ciblées et `git diff --check` sont exécutées. Basculer vers
|
||||||
|
le workflow normal si la complexité dépasse une correction locale.
|
||||||
|
|
||||||
|
## E. Quota Codex renouvelé
|
||||||
|
|
||||||
|
GPT-5.6 Sol visible dans OpenCode est une offre Zen payante, pas une voie Codex
|
||||||
|
confirmée. Lancer `/lardon-codex-handoff`, copier le prompt court produit dans
|
||||||
|
Codex CLI, puis utiliser Codex directement. Aucune clé n'est copiée entre les
|
||||||
|
outils.
|
||||||
|
|
||||||
|
## F. Retour depuis Codex
|
||||||
|
|
||||||
|
Lancer `/lardon-resume-from-codex`. OpenCode lit le handoff et le diff laissé
|
||||||
|
par Codex, puis effectue revue et tests sans refaire l'architecture. Le handoff
|
||||||
|
est ensuite actualisé.
|
||||||
|
|
||||||
|
## G. GPT-5.6 Sol direct dans OpenCode
|
||||||
|
|
||||||
|
Ce scénario est désactivé : Q1 n'est pas confirmé. Il ne pourra être ajouté que
|
||||||
|
si une route ChatGPT/Codex officiellement supportée, sans facturation Zen ou API
|
||||||
|
distincte, et une consommation du quota Codex sont toutes prouvées.
|
||||||
|
|
||||||
|
## H. Authentification directe avec quota inconnu
|
||||||
|
|
||||||
|
Le cas Q2 n'a pas été observé. S'il apparaît plus tard, aucune utilisation ne
|
||||||
|
doit être automatique : documenter le fournisseur et le risque, puis obtenir une
|
||||||
|
décision explicite avant une commande expérimentale.
|
||||||
|
|
||||||
|
## I. Fallback payant interdit
|
||||||
|
|
||||||
|
La configuration ne référence que des modèles explicitement gratuits. Une panne
|
||||||
|
de tous les secours gratuits arrête le ticket en conservant le handoff. Elle ne
|
||||||
|
doit jamais sélectionner `big-pickle`, GPT-5.6 Sol ou un autre modèle tarifé ou
|
||||||
|
de statut inconnu.
|
||||||
|
|
||||||
|
## Chargement progressif
|
||||||
|
|
||||||
|
1. Lire AGENTS.md et l'overview injectés par la configuration.
|
||||||
|
2. Faire identifier par explore les seuls fichiers et documents utiles.
|
||||||
|
3. Charger ces documents seulement ; appeler architect si une abstraction est
|
||||||
|
touchée.
|
||||||
|
4. Transmettre à l'implémenteur un résumé concis, jamais les documents complets.
|
||||||
|
5. Appeler uniquement les validations et revues pertinentes.
|
||||||
|
|
||||||
|
Pour une reprise, commencer par le handoff et le diff. Les sorties intermédiaires
|
||||||
|
ne conservent que conclusions, risques, fichiers, commandes, erreurs et
|
||||||
|
décisions ; les longs logs et les sources complètes sont exclus.
|
||||||
140
src/task_queue.c
140
src/task_queue.c
|
|
@ -34,6 +34,82 @@ terminal_state(Lardon3DTaskState state)
|
||||||
|| state == TASK_COMPLETED;
|
|| state == TASK_COMPLETED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
unlink_pending(Lardon3DTaskQueue *queue, TaskNode *previous, TaskNode *node)
|
||||||
|
{
|
||||||
|
if (previous) {
|
||||||
|
previous->next_pending = node->next_pending;
|
||||||
|
} else {
|
||||||
|
queue->pending_head = node->next_pending;
|
||||||
|
}
|
||||||
|
if (queue->pending_tail == node) {
|
||||||
|
queue->pending_tail = previous;
|
||||||
|
}
|
||||||
|
node->next_pending = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parcourt la file d'attente et sélectionne la première tâche admissible.
|
||||||
|
* Les tâches terminales ou refusées sont retirées de la file d'attente.
|
||||||
|
* Une tâche en attente de ressources reste en file et sera réévaluée.
|
||||||
|
* Retourne NULL si aucune tâche ne peut démarrer immédiatement. */
|
||||||
|
static Lardon3DTask *
|
||||||
|
select_admissible(
|
||||||
|
Lardon3DTaskQueue *queue,
|
||||||
|
Lardon3DResourceReservation **reservation
|
||||||
|
)
|
||||||
|
{
|
||||||
|
TaskNode *previous = NULL;
|
||||||
|
TaskNode *node = queue->pending_head;
|
||||||
|
while (node) {
|
||||||
|
TaskNode *next = node->next_pending;
|
||||||
|
Lardon3DTaskSnapshot task_snapshot;
|
||||||
|
if (!lardon3d_task_snapshot(node->task, &task_snapshot)) {
|
||||||
|
unlink_pending(queue, previous, node);
|
||||||
|
node = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (terminal_state(task_snapshot.state)) {
|
||||||
|
unlink_pending(queue, previous, node);
|
||||||
|
node = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Lardon3DResourceEstimate estimate;
|
||||||
|
Lardon3DResourceDecision decision;
|
||||||
|
Lardon3DResourceReservation *candidate = NULL;
|
||||||
|
bool evaluated = lardon3d_task_resource_estimate(node->task, &estimate)
|
||||||
|
&& lardon3d_resource_governor_reserve_available(
|
||||||
|
queue->governor,
|
||||||
|
&estimate,
|
||||||
|
&decision,
|
||||||
|
&candidate
|
||||||
|
);
|
||||||
|
if (!evaluated) {
|
||||||
|
(void)lardon3d_task_reject(
|
||||||
|
node->task,
|
||||||
|
"Impossible d'évaluer les ressources disponibles."
|
||||||
|
);
|
||||||
|
unlink_pending(queue, previous, node);
|
||||||
|
node = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (decision.kind == LARDON3D_RESOURCE_WAIT) {
|
||||||
|
previous = node;
|
||||||
|
node = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (decision.kind == LARDON3D_RESOURCE_REJECT || !candidate) {
|
||||||
|
(void)lardon3d_task_reject(node->task, decision.reason);
|
||||||
|
unlink_pending(queue, previous, node);
|
||||||
|
node = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
unlink_pending(queue, previous, node);
|
||||||
|
*reservation = candidate;
|
||||||
|
return node->task;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
queue_worker(void *context)
|
queue_worker(void *context)
|
||||||
{
|
{
|
||||||
|
|
@ -47,64 +123,19 @@ queue_worker(void *context)
|
||||||
(void)pthread_mutex_unlock(&queue->mutex);
|
(void)pthread_mutex_unlock(&queue->mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
TaskNode *node = queue->pending_head;
|
|
||||||
Lardon3DTaskSnapshot task_snapshot;
|
|
||||||
if (!lardon3d_task_snapshot(node->task, &task_snapshot)) {
|
|
||||||
(void)pthread_mutex_unlock(&queue->mutex);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (terminal_state(task_snapshot.state)) {
|
|
||||||
queue->pending_head = node->next_pending;
|
|
||||||
if (!queue->pending_head) {
|
|
||||||
queue->pending_tail = NULL;
|
|
||||||
}
|
|
||||||
node->next_pending = NULL;
|
|
||||||
(void)pthread_mutex_unlock(&queue->mutex);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Lardon3DResourceEstimate estimate;
|
|
||||||
Lardon3DResourceDecision decision;
|
|
||||||
Lardon3DResourceReservation *reservation = NULL;
|
Lardon3DResourceReservation *reservation = NULL;
|
||||||
bool evaluated = lardon3d_task_resource_estimate(node->task, &estimate)
|
Lardon3DTask *selected = select_admissible(queue, &reservation);
|
||||||
&& lardon3d_resource_governor_reserve_available(
|
if (!selected) {
|
||||||
queue->governor,
|
|
||||||
&estimate,
|
|
||||||
&decision,
|
|
||||||
&reservation
|
|
||||||
);
|
|
||||||
if (!evaluated) {
|
|
||||||
(void)lardon3d_task_reject(
|
|
||||||
node->task,
|
|
||||||
"Impossible d'évaluer les ressources disponibles."
|
|
||||||
);
|
|
||||||
(void)pthread_mutex_unlock(&queue->mutex);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (decision.kind == LARDON3D_RESOURCE_WAIT) {
|
|
||||||
(void)pthread_cond_wait(&queue->condition, &queue->mutex);
|
(void)pthread_cond_wait(&queue->condition, &queue->mutex);
|
||||||
(void)pthread_mutex_unlock(&queue->mutex);
|
(void)pthread_mutex_unlock(&queue->mutex);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (decision.kind == LARDON3D_RESOURCE_REJECT || !reservation) {
|
queue->active = selected;
|
||||||
(void)lardon3d_task_reject(node->task, decision.reason);
|
|
||||||
(void)pthread_mutex_unlock(&queue->mutex);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
queue->pending_head = node->next_pending;
|
|
||||||
if (!queue->pending_head) {
|
|
||||||
queue->pending_tail = NULL;
|
|
||||||
}
|
|
||||||
node->next_pending = NULL;
|
|
||||||
queue->active = node->task;
|
|
||||||
(void)pthread_mutex_unlock(&queue->mutex);
|
(void)pthread_mutex_unlock(&queue->mutex);
|
||||||
|
|
||||||
if (!lardon3d_task_start(
|
if (!lardon3d_task_start(selected, queue->governor, reservation)) {
|
||||||
node->task,
|
|
||||||
queue->governor,
|
|
||||||
reservation
|
|
||||||
)) {
|
|
||||||
(void)lardon3d_task_reject(
|
(void)lardon3d_task_reject(
|
||||||
node->task,
|
selected,
|
||||||
"Réservation de ressources invalide."
|
"Réservation de ressources invalide."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -290,14 +321,7 @@ lardon3d_task_queue_remove(Lardon3DTaskQueue *queue, uint64_t task_id)
|
||||||
pending = pending->next_pending;
|
pending = pending->next_pending;
|
||||||
}
|
}
|
||||||
if (pending) {
|
if (pending) {
|
||||||
if (pending_previous) {
|
unlink_pending(queue, pending_previous, pending);
|
||||||
pending_previous->next_pending = pending->next_pending;
|
|
||||||
} else {
|
|
||||||
queue->pending_head = pending->next_pending;
|
|
||||||
}
|
|
||||||
if (queue->pending_tail == pending) {
|
|
||||||
queue->pending_tail = pending_previous;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
--queue->count;
|
--queue->count;
|
||||||
(void)pthread_mutex_unlock(&queue->mutex);
|
(void)pthread_mutex_unlock(&queue->mutex);
|
||||||
|
|
|
||||||
|
|
@ -296,6 +296,74 @@ run_test(void)
|
||||||
lardon3d_task_queue_destroy(queue);
|
lardon3d_task_queue_destroy(queue);
|
||||||
CHECK(pthread_mutex_destroy(&wait_log.mutex) == 0);
|
CHECK(pthread_mutex_destroy(&wait_log.mutex) == 0);
|
||||||
|
|
||||||
|
/* Une tâche de tête bloquée en WAIT ne doit pas empêcher une tâche
|
||||||
|
admissible située derrière elle de démarrer. */
|
||||||
|
Lardon3DResourceSnapshot io_blocking_snapshot = {
|
||||||
|
.memory_available_bytes = UINT64_MAX,
|
||||||
|
.cpu_load_1m = 0.0,
|
||||||
|
};
|
||||||
|
Lardon3DResourceEstimate io_blocking_estimate = {
|
||||||
|
.minimum_batch_size = 1,
|
||||||
|
.maximum_batch_size = 1,
|
||||||
|
.desired_cpu_threads = 1,
|
||||||
|
.desired_io_slots = 1,
|
||||||
|
};
|
||||||
|
Lardon3DResourceDecision io_decision;
|
||||||
|
Lardon3DResourceReservation *io_blocking_reservation;
|
||||||
|
CHECK(lardon3d_resource_governor_reserve(
|
||||||
|
governor,
|
||||||
|
&io_blocking_snapshot,
|
||||||
|
&io_blocking_estimate,
|
||||||
|
&io_decision,
|
||||||
|
&io_blocking_reservation
|
||||||
|
));
|
||||||
|
CHECK(io_blocking_reservation);
|
||||||
|
queue = lardon3d_task_queue_create(governor);
|
||||||
|
CHECK(queue);
|
||||||
|
OrderLog bypass_log = {0};
|
||||||
|
CHECK(pthread_mutex_init(&bypass_log.mutex, NULL) == 0);
|
||||||
|
Lardon3DResourceEstimate io_estimate = {
|
||||||
|
.minimum_batch_size = 1,
|
||||||
|
.maximum_batch_size = 1,
|
||||||
|
.desired_cpu_threads = 1,
|
||||||
|
.desired_io_slots = 1,
|
||||||
|
};
|
||||||
|
QueueWork blocked = {.log = &bypass_log, .value = 1, .steps = 1};
|
||||||
|
Lardon3DTask *blocked_task = lardon3d_task_create(
|
||||||
|
"Bloquée en tête",
|
||||||
|
&io_estimate,
|
||||||
|
queue_callback,
|
||||||
|
&blocked
|
||||||
|
);
|
||||||
|
uint64_t blocked_id;
|
||||||
|
CHECK(blocked_task);
|
||||||
|
CHECK(lardon3d_task_queue_add(queue, blocked_task, &blocked_id));
|
||||||
|
QueueWork bypass = {.log = &bypass_log, .value = 2, .steps = 1};
|
||||||
|
Lardon3DTask *bypass_task = lardon3d_task_create(
|
||||||
|
"Admissible derrière",
|
||||||
|
&estimate,
|
||||||
|
queue_callback,
|
||||||
|
&bypass
|
||||||
|
);
|
||||||
|
uint64_t bypass_id;
|
||||||
|
CHECK(bypass_task);
|
||||||
|
CHECK(lardon3d_task_queue_add(queue, bypass_task, &bypass_id));
|
||||||
|
CHECK(wait_terminal(queue, bypass_id, &snapshot));
|
||||||
|
CHECK(snapshot.state == TASK_COMPLETED);
|
||||||
|
CHECK(bypass.contract_seen);
|
||||||
|
CHECK(lardon3d_task_queue_get(queue, blocked_id, &snapshot));
|
||||||
|
CHECK(snapshot.state == TASK_PENDING);
|
||||||
|
CHECK(!blocked.contract_seen);
|
||||||
|
CHECK(lardon3d_resource_governor_release(governor, io_blocking_reservation));
|
||||||
|
lardon3d_task_queue_resources_changed(queue);
|
||||||
|
CHECK(wait_terminal(queue, blocked_id, &snapshot));
|
||||||
|
CHECK(snapshot.state == TASK_COMPLETED);
|
||||||
|
CHECK(blocked.contract_seen);
|
||||||
|
CHECK(bypass_log.count == 2);
|
||||||
|
CHECK(lardon3d_resource_governor_reservation_count(governor) == 0);
|
||||||
|
lardon3d_task_queue_destroy(queue);
|
||||||
|
CHECK(pthread_mutex_destroy(&bypass_log.mutex) == 0);
|
||||||
|
|
||||||
queue = lardon3d_task_queue_create(governor);
|
queue = lardon3d_task_queue_create(governor);
|
||||||
CHECK(queue);
|
CHECK(queue);
|
||||||
OrderLog contract_log = {0};
|
OrderLog contract_log = {0};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue