Base de connaissances persistante lue par Claude à chaque session démarrée dans ce dépôt. Centralise le contexte vital pour être opérationnel immédiatement, sans ré-explication. Toute erreur ou préférence durable doit être consignée ici (apprentissage itératif).
Dernière mise à jour : 2026-06-22 — v6.1.0 (ajout P11/P12 + décisions associées suite aux sprints 1-4 du hardening)
| Besoin | Aller à |
|---|---|
| Démarrer une session | §18 |
| Comprendre l'architecture | §1, §3 |
| Connaître la stack | §2 |
| Coder dans le loop agent | §7 + §16 |
| Écrire un plugin | §1, §7 |
| Modifier le shell Electron / IPC | §9, §13, §16 |
| Committer proprement | §11 |
| Déboguer un bug | §6 |
| Éviter un piège connu | §7.4 (P1-P10) |
| Vérifier avant PR | §10 |
| Sécurité | §13 |
| Mémoire & sauvegardes | §17 |
OPC (Open Project Cockpit) est une application desktop Electron + CLI Node/TypeScript qui pilote un agent de coding autonome. Elle combine :
- une boucle agentique (act → observe → reason → repeat) de type ReAct ;
- une couche Human-in-the-Loop via IPC Electron ;
- un système de plugins inspiré de Claude Code ;
- un bridge CLI ↔ Electron avec streaming d'événements JSON-lines.
La couche src/ est principalement un vendoring/fork de Claude Code upstream. Toute la valeur ajoutée OPC vit dans src/utils/ (loop), desktop/electron/ (IPC) et plugins/.
Versions précises dans package.json (racine + desktop/). Spécificités à retenir :
- TypeScript strict côté
src/, CommonJS.cjscôtédesktop/electron/(mélanger ESM dansdesktop/casse Electron). - Trois
tsconfigdistincts, tousnoEmit(pas de bundle,tsxexécute directement) :
| Fichier | Périmètre |
|---|---|
tsconfig.check.json |
Typecheck global du refactor |
tsconfig.utils.json |
Coeur loop (src/utils/) |
tsconfig.loop-tests.json |
Tests loop (src/utils/__tests__/) |
- Tests :
node:testnatif (pas de framework tiers), vianpm run verify:ci. - Tooling : Electron
^39.8.10, electron-builder^26.8.1, Ink pour CLI React-like,tsx ^4.22.4.
| Dossier | Rôle |
|---|---|
src/utils/ |
Coeur OPC : loop, budget, reasoner, context, humanGate, JSONL |
src/utils/__tests__/ |
Tests node:test (82 cas) |
src/commands/, src/plugins/ |
CLI + plugins utilisateur |
desktop/electron/ |
Shell Electron CommonJS strict (main, IPC, cliRunner, sessionStore) |
desktop/test/, desktop/renderer/ |
Tests Electron (310 cas) + UI navigateur |
plugins/ |
16 plugins utilisateur (agent-sdk-dev, hookify, ...) |
docs/ |
Audits, specs, guides (référence clé : docs/OPC_LOOP_ENGINEERING_AUDIT_2026-06-21.md) |
| Catégorie | Convention | Exemple |
|---|---|---|
| Fichiers TS | kebab-case.ts |
loopRunner.ts, contextBudget.ts |
| Fichiers CJS Electron | camelCase.cjs |
cliRunner.cjs, humanGateIpc.cjs |
| Composants JSX | PascalCase.tsx |
ConfirmationBanner.tsx |
| Tests | <module>.test.ts / <module>.test.cjs |
loopBudget.test.ts |
| Fonctions exportées | camelCase |
evaluateStop, dispatchReason |
| Types/Interfaces | PascalCase |
LoopEvent, Reasoner, BudgetTracker |
| Constantes globales | UPPER_SNAKE |
MAX_ITERS, DEFAULT_TIMEOUT_MS |
| Variables privées | préfixe _ ou private TS |
_abortController |
| Branches git | <type>-<scope> en kebab-case |
opc-production-hardening |
Obligatoire pour toute tâche de livraison. Choisir le type :
| Type | Quand l'utiliser |
|---|---|
| Artefact | Code, composant, plugin, refactor |
| Prose | Documentation, rédaction, README, CLAUDE.md |
| Analyse | Recherche, comparaison, exploration |
| Audit | Revue, diagnostic, post-mortem |
Produire → 1ère passe du livrable (code, doc, analyse)
↓
Observer → relire, vérifier la sortie réelle (lint/test/diff), comparer au but
↓
Capturer → noter l'écart : bug, dérive, décision non documentée
↓
Corriger → patcher + vérifier que le fix tient + mettre à jour CLAUDE.md si durable
↓
(rebouclage si écart restant)
Règles absolues :
- Pensée dense — réfléchir avant d'agir.
- Livrable fini — pas de placeholder, TODO, ni "à compléter".
- Auto-correction — relire systématiquement avant de répondre.
- Vérité objective — citer le résultat réel, pas l'espéré.
- Note de confiance finale obligatoire (haute / moyenne / basse) sur toute analyse ou audit.
Pour chaque tâche de code :
- ORIENTER — lire les fichiers concernés,
git status, branche courante. - LIRE —
read_filesur TOUT ce qui sera modifié (jamais de mémoire). - PLANIFIER — lister les changements AVANT de commencer.
- EXÉCUTER — changements ciblés, empreintes minimales.
- VÉRIFIER —
npm run verify:ci(racine) +npm --prefix desktop run verify:ci. - COMMITTER — Conventional Commits en français, scope explicite.
Pour les tâches ≥ 3 étapes : utiliser TodoWrite pour suivre l'avancement.
Pour le débogage : reproduire → chercher le message → cause racine → fix → chercher bugs similaires.
Référence clé : docs/OPC_LOOP_ENGINEERING_AUDIT_2026-06-21.md.
Boucle principale : Act → Observe → Verify → Reason → Repeat avec bornes budgets.
| Fichier | Rôle | Exports clés |
|---|---|---|
src/utils/loopRunner.ts |
Orchestrateur principal | runLoop, dispatchReason |
src/utils/loopBudget.ts |
BudgetTracker + sterile-action | BudgetTracker, actionKey |
src/utils/loopStop.ts |
Critère d'arrêt central | evaluateStop() |
src/utils/loopReasoner.ts |
ReAct pluggable (LLM ou heuristique) | defaultReason, isTransientFailure |
src/utils/humanInTheLoop.ts |
Interface HumanGate |
noHumanGate, createIpcHumanGate |
src/utils/loopEvents.ts |
Union typée + emitter | LoopEvent, LoopEventEmitter |
Autres modules de support (events JSONL, context budget, vérification, criteria, tool registry, task checklist, memory) : voir arborescence src/utils/ et __tests__/.
| Cas | Décision | Effet |
|---|---|---|
act-fail transient, attempt < 2 |
retry |
Compteur incrémenté |
act-fail déterminist (TypeError, ENOENT) |
escalate |
Sortie immédiate |
act-fail transient, confidence basse |
ask-human |
Prompt IPC |
verify-ok |
continue (done) |
Tâche marquée done |
verify-fail attempt ≤ 2 |
refine |
Texte tâche mis à jour |
verify-fail attempt > 2 |
ask-human ou escalate |
Selon confidence |
human-approved |
continue |
Override verify-fail |
human-rejected |
escalate |
Sortie immédiate |
human-timeout |
retry |
Compteur préservé |
Boucle jamais bloquée (timeout = pire cas borné), defaultReason toujours dispo en fallback, IPC safe (erreur résout 'timeout'), refine commit immédiat avant le tour suivant.
Lecture obligatoire avant toute modification loop ou IPC. Chaque piège cite la conséquence d'ignorance.
| # | Piège | Conséquence si ignoré |
|---|---|---|
| P1 | Émettre loop_finished en fin de boucle, sans exception |
Renderer reste sur "running" indéfiniment, l'utilisateur ne voit jamais l'état terminal |
| P2 | actionKey du BudgetTracker doit inclure un identifiant sémantique (tool + target + argsHash), pas juste le tool name |
Les retries légitimes ne déclenchent pas la détection de boucle stérile → escalade absente |
| P3 | Mettre à jour tsconfig.utils.json ET tsconfig.loop-tests.json pour tout nouveau fichier src/utils/*.ts |
Le nouveau module n'est pas typechecké ; les tests ne le voient pas ; CI silencieusement verte mais fausse |
| P4 | Conserver le préfixe opc: sur tous les canaux IPC cliRunner.cjs ↔ loopEventIpc.cjs |
Renommer un canal casse le bridge CLI↔Electron silencieusement (événement jamais reçu côté renderer) |
| P5 | Tests Electron en .cjs : exécution via node --test, pas via Electron |
Importer electron dans un test unit .cjs casse le runner ; les helpers doivent être neutres |
| P6 | Boucle while (true) interdite : utiliser evaluateStop() systématiquement |
Risque de boucle infinie, dépassement budget, deadlock IPC |
| P7 | Reasoner qui throw : wrapper systématiquement dans try/catch + fallback defaultReason |
Une exception LLM remonte jusqu'au renderer et casse la session |
| P8 | IPC handler qui throw : retourner { ok: false, error }, ne jamais propager |
Le renderer reçoit une exception non gérée ; état UI incohérent, pas de recovery |
| P9 | Tests qui mockent le système de fichiers entier : préférer os.tmpdir() + cleanup explicite |
Tests qui passent en mock mais échouent en intégration ; pollution du repo |
| P10 | Validation IPC obligatoire via desktop/electron/ipcValidation.cjs : ne JAMAIS bypasser |
Canal non validé = faille XSS, command injection ou path traversal exploitable depuis le renderer |
| P11 | Buffers texte IPC/stream bornés via appendBoundedText(current, next, maxChars) qui conserve la queue (slice(-maxChars)), pas la tête |
Un stdout de loop agentique est un flux infini : garder le début = perdre toute l'info utile ; un buffer non borné = OOM et freeze IPC |
| P12 | webContents.send toujours wrappé via createSendChannel({ getMainWindow, log }) qui no-op sur mainWindow == null, mainWindow.isDestroyed(), webContents == null, webContents.isDestroyed(), et qui swallow toute exception de send() |
Renderer crashé ou fenêtre en cours de teardown → send jette synchroniquement, pollue les logs main-process et casse la session ; un canal non protégé = crash en cascade |
Une session OPC conforme à ce baseline présente ces signaux :
| Signal | Indicateur |
|---|---|
| Lecture initiale | CLAUDE.md + fichiers touchés lus avant toute édition |
| Plan | TodoWrite activé pour ≥ 3 étapes ; tâches marquées in_progress puis completed sans skip |
| Vérification | npm run verify:ci ET npm --prefix desktop run verify:ci verts après chaque modification |
| Livrable | Code complet (pas de TODO, pas de placeholder), note de confiance finale |
| Mémoire | Pièges nouveaux capturés dans §7.4 (P1-P10) si récurrents |
| Commit | Conventional Commits FR, scope explicite, tests verts en local |
| Style | Réponses concises, pyramide inversée, chiffres plutôt qu'adjectifs |
Si 2 de ces signaux sont absents, stop & corriger avant de continuer :
- ❌ Modification sans lecture préalable du fichier
- ❌ Tests non lancés après changement de comportement
- ❌ Livrable avec placeholder ou "à compléter"
- ❌ Commit sans message conventionnel ou avec secrets en dur
- ❌ Boucle d'apprentissage §5.1 non appliquée (pas d'observation, pas de correction)
- ❌ Piège connu P1-P10 ignoré malgré rappel
- ❌ Note de confiance absente sur analyse/audit
- ❌
console.loglaissé en production
Principes directeurs pour le shell Electron et le renderer OPC :
- Latence perceptible : tout délai > 200 ms doit être signalé (état transitoire visible).
- Confirmations destructrices : suppression de session, kill de loop, reset budget → toujours via bannière (
ConfirmationBanner.js) avec raison explicite. - Stream JSONL : le renderer doit afficher les événements au fil de l'eau, pas en bloc en fin de boucle.
- Couleurs sémantiques : rouge = erreur/timeout, jaune = ask-human/en attente, vert = done, gris = idle.
- Accessibilité : contrastes WCAG AA, navigation clavier pour les actions critiques (Enter = confirmer, Esc = annuler).
- Pas de blocking modal : les bannières sont non-bloquantes ; le user peut continuer à lire le stream.
Référence : desktop/renderer/services/confirmationBanner.js, desktop/renderer/services/sessionBanner.js.
| Commande | Périmètre |
|---|---|
npm run verify:ci |
typecheck:refactor + typecheck:utils + typecheck:loop-tests + test:loop + chaîne desktop |
npm --prefix desktop run verify:ci |
audit:security (npm audit --audit-level=moderate --omit=optional) + typecheck:refactor + test (node --test test/*.test.cjs) |
- Tests loop :
82/82doivent rester verts (src/utils/__tests__/). - Tests Electron :
310/310doivent rester verts (desktop/test/*.test.cjs). - Typecheck :
0 erreursur les 3 tsconfig.
Tout PR qui régresse l'un de ces seuils est rejeté sauf raison documentée.
Format : <type>(<scope>): <sujet> + corps optionnel en français.
| Type | Usage |
|---|---|
feat |
Nouvelle fonctionnalité utilisateur |
fix |
Correction de bug |
refactor |
Refacto sans changement de comportement |
docs |
Documentation seule |
chore |
Maintenance (deps, config, CI) |
perf |
Optimisation mesurable |
test |
Ajout ou correction de tests |
style |
Formatage seul |
Toutes les règles s'appliquent sans exception. Une règle enfreinte = livrable refusé.
- Pas de catch silencieux (
except: pass,catch(e) {}) — toujours logger ou propager. - Pas d'
eval()avec des données utilisateur — risque d'injection. - Pas de
var— utiliserconstpar défaut,letsi mutation nécessaire. - Pas de secrets hardcodés — variables d'environnement, jamais en dur dans le code.
- Pas de
rm -rfsans confirmation explicite — risque de destruction irréversible.
- Pas de push vers
main/mastersans tests verts en local + revue si branche partagée.
- Pas de
console.logen production — utiliserloopEventsouconsole.error. - Pas de
anyTypeScript — utiliserunknown+ narrow (TS strict). - Toujours documenter les side-effects IPC dans
preload.cjsETipcContract.cjs. - Toujours émettre un
LoopEventpour chaque transition d'état de la boucle. - Toujours valider les inputs aux frontières (user input, IPC, API).
- Ne jamais modifier CLAUDE.md en spéculation — un ajout (règle, piège, décision) n'est consigné qu'après validation explicite par l'utilisateur ou après deux occurrences confirmées du même problème. Avant cela, le brouillon vit dans
.claude/MEMORY.mdou dans le worklog de session.
- IPC validation :
desktop/electron/ipcValidation.cjsvalide chaque canal. Ne JAMAIS bypasser (= piège P10). - Path traversal : résoudre tous les chemins via
path.resolvepuis vérifier préfixe autorisé. - Command injection :
cliRunner.cjsdoit passer parexeca/spawnavec args en array, JAMAIS deexec(string). - Render XSS : tout HTML injecté dans le renderer doit passer par un sanitizer (DOMPurify si dispo).
- Dependencies :
audit:security(moderate) doit rester clean avant tout PR.
Cette section consigne les décisions architecturales durables. Les pièges récurrents sont centralisés en §7.4 (P1-P10) — ne pas dupliquer ici.
src/utils/est en TypeScript strict avecnoEmit. Pas de webpack/esbuild, tsx exécute directement. Toute tentative d'ajouter un bundler doit être justifiée.- CommonJS strict dans
desktop/electron/(suffixe.cjs). Mélanger ESM dansdesktop/casse Electron. - Les modules loop sont sans dépendance externe runtime : ils n'importent que des types Node natifs. C'est ce qui permet
tsconfig.utils.jsonde typer sansnode_modulescomplets. humanGateIpc.cjsest fail-safe par construction : toute erreur résout'timeout', jamais d'exception.- Buffers texte bornés (
appendBoundedText, P11) : utiliser systématiquement pour stdout/stderr et tout flux infini susceptible de transiter par IPC ; exporter le helper depuis un module neutre pour réutilisation (cf.cliRunner.cjs:129). - Tout
webContents.sendpasse parcreateSendChannel(P12) : import depuisdesktop/electron/sendChannel.cjs, jamais d'appel direct àmainWindow.webContents.senddepuis les handlers IPC ; garantit le no-op sûr sur fenêtre détruite et évite les exceptions silencieuses.
| Terme | Signification |
|---|---|
| ReAct | Pattern Reason + Act entrelacés à chaque tour |
| HumanGate | Interface d'escalade humaine (ask(payload) → approved/rejected/timeout) |
| BudgetTracker | Compteur tokens/USD/wall-time + détection de boucle stérile |
| Sterile action | Action répétée sans progrès (≥ 3 fois) → escalade automatique |
actionKey |
Clé sémantique pour détecter les repeats (tool + target + argsHash) |
evaluateStop |
Fonction centrale de décision d'arrêt (abort / budget / fatal / done) |
Pour toute intervention loop, toujours lire ces fichiers en premier :
src/utils/loopRunner.ts # orchestrateur
src/utils/loopBudget.ts # budget + sterile detection
src/utils/loopStop.ts # evaluateStop
src/utils/loopEvents.ts # types d'événements
src/utils/loopReasoner.ts # ReAct
src/utils/humanInTheLoop.ts # interface HumanGate
desktop/electron/ipc/humanGateIpc.cjs # bridge IPC human
desktop/electron/ipc/loopEventIpc.cjs # bridge IPC events
desktop/electron/cliRunner.cjs # spawn CLI + stream JSONL
docs/OPC_LOOP_ENGINEERING_AUDIT_2026-06-21.md # état de l'art loop
- Mémoire projet long terme :
.claude/MEMORY.md(journal auto-généré, ne pas éditer à la main sauf décision durable). - Mémoire personnelle utilisateur :
~/.claude/CLAUDE.md(chargée globalement, priorité basse par rapport à ce fichier). - Mémoire globale projet :
~/.claude/projects/-Users-bayeasssene-Documents-ProjetsGithub-OPC/memory/(faits, feedback, references).
Pour une préférence durable (ex. "toujours valider avant commit"), demander explicitement "ajoute ça au CLAUDE.md" pour qu'elle soit consignée (cf. R12).
git status # 1. État du repo
npm run verify:ci # 2. Référence : tout doit être vertIdentifier le scope : src/utils/* (loop) | desktop/electron/* (IPC) | plugins/* (extension) | docs/* (audit/spec). Puis suivre §6.
- Lire §Index rapide → identifier les 2-3 sections pertinentes.
- Si intervention loop : §16 (fichiers critiques) → §7 (boucle) → §7.4 (pièges P1-P10).
- Si intervention IPC : §13 (sécurité) + §16 + piège P10.
- Lancer
verify:ci(§10.1) pour baseline avant toute modification. - Au moindre doute : §8.2 (indicateur de dérive) pour auto-évaluer.
Confiance globale sur ce fichier : haute sur stack/architecture/baselines/pièges P1-P10 ; moyenne sur conventions de nommage et Design & UX (à confirmer sur l'ensemble du repo après 2-3 sessions d'usage).