Modèle as-is · avril 2026

SDEG Kernel — le code comme modèle du domaine

Description fidèle de l'état actuel du noyau de software development engineering generative — sans proposition, sans correction.

Repo : sdeg-kernel Branch : main 58 tests verts 14 / 42 portes automatisées Node ≥ 18 · zéro dépendance

1. Intention

Le projet vise un système de développement logiciel génératif. Son postulat : le besoin utile n'est jamais donné à l'avance — il se découvre par itération. Le logiciel n'est pas la réponse à une spécification ; il est le moyen d'éprouver une hypothèse de valeur.

La posture épistémique est herméneutique : chaque cycle de conception est une lecture du besoin, qui modifie la compréhension du besoin lui-même. L'objectif n'est pas la conformité à un cahier des charges, mais l'obtention rapide d'une solution minimale utilisable et utile, dont l'usage révèle la prochaine question.

Pour soutenir cette démarche, le noyau sdeg-kernel fait trois choses :

  1. Il matérialise le domaine en code. La machine d'états (schema.js) est la définition exécutable du cycle de décision. Lire le code, c'est lire le modèle.
  2. Il sépare strictement ce qui est décidé de ce qui est en cours. Tout artefact est soit LIVING (mutable), soit COLD (figé). Une porte franchie gèle le passé ; on n'y revient pas, on ouvre un nouveau grain.
  3. Il délègue la production à l'IA, garde la décision à l'humain. Les agents produisent les artefacts, le CLI fait avancer les états. Seul un humain déclenche une transition.

Hypothèse centrale du modèle

La connaissance utile émerge du cycle mesurable hypothèse → artefact minimal → mise en usage → mesure → décision. Le rôle du kernel est de rendre ce cycle court, traçable et non-destructif.

2. Vue d'ensemble du kernel

Le kernel est un petit outil Node.js (~1 200 lignes, sans dépendance externe) qui combine trois briques :

Déterministe

Un CLI (sdlc/sdlc.js), une machine d'états (sdlc/schema.js), un évaluateur de portes (sdlc/evaluator.js), une bibliothèque de validateurs (sdlc/validators.js). Aucune IA dans cette couche. C'est elle qui garde la mémoire et la forme.

Génératif

1 agent orchestrateur (.github/agents/coach-emergent) + 16 assistants spécialisés (.github/prompts/*). Chacun produit un artefact précis — EHS, LBC, OKR, feature spec, user story, code TDD. C'est eux qui portent le contenu et l'exploration.

Rituel

Hooks PowerShell (scripts/*.ps1) et hook git pre-commit (sdlc/install-hooks.js). Ils déclenchent les bons chargements au bon moment : démarrage de session, protection mémoire, refus de registre corrompu au commit.

Journal

Deux sources de vérité vivantes : le registre .product/sdlc-registry.json (état courant + historique) et le dossier d'événements .product/.events/*.md (un fichier markdown par transition, commité avec le registre).

Arborescence

sdeg-kernel/
├── sdlc/                  ← noyau déterministe
│   ├── schema.js            machine d'états (SSOT)
│   ├── validators.js        12 validateurs purs
│   ├── evaluator.js         moteur de verdict (GO / NEEDS-REVIEW / NO-GO)
│   ├── sdlc.js              CLI — seul mutateur d'état
│   ├── frontmatter.js       parser YAML minimal
│   ├── install-hooks.js     installeur git pre-commit
│   ├── SDLC.md              doc humaine de la machine
│   └── __tests__/           58 tests (node:test)
├── .github/
│   ├── agents/            ← 1 mode agent "Coach"
│   └── prompts/           ← 16 assistants spécialisés
├── meta/
│   └── template-eo.md       modèle d'Étude d'Opportunité
├── scripts/               ← hooks PowerShell (session, safety)
├── docs/
│   ├── specs/               specs d'implémentation (ex : vague 3)
│   └── as-is/               cette description (modèle as-is)
├── README.md · GUIDE.html · LICENSE

3. Le domaine, tel qu'il est nommé

Le kernel distingue trois types d'objets et cinq méta-états. C'est la totalité du vocabulaire formel.

Types d'objets (schema.js:TYPES)

CodeNomGranularitéParent requis
beBusiness Epic≥ 2 trimestres, impact multi-équipes—
feFeature1 PI (programme increment)une BE
usRécit (User Story)1 sprintune FE

La filiation est obligatoire descendante et vérifiée à la création par le CLI (sdlc.js:PARENT_RULES, ligne 276). Un objet en statut terminal (TERMINE, PIVOTED, LIVRE, ARCHIVED, VALIDE) ne peut plus servir de parent à un nouvel objet.

Méta-états (schema.js:META)

MétaHeatSensBadge
NOT_STARTEDcoldAmbition non engagée○
IN_PROGRESSlivingArtefact mutable — la décision n'est pas prise●
BLOCKEDliving-frozenGelé par dépendance externe, pas abandonné◐
DONEcoldDécision prise, artefacts figés✓
ARCHIVEDcoldDéprioritisé, historique préservé✕

Principe LIVING / COLD

Le heat est dérivé du méta-état. Un artefact LIVING est librement modifiable ; un artefact COLD est considéré gelé — si on doit le changer, on ouvre un nouveau cycle (pivot, persévère). Cette règle est la pierre angulaire du modèle : elle interdit la réécriture silencieuse du passé.

4. La machine d'états

Chaque type a son propre graphe de statuts. Les arêtes (transitions) portent le nom de la porte décisionnelle, les prérequis humains, les artefacts gelés, et — optionnellement — des invariants et checks exécutables.

Business Epic — 10 statuts

NOT_STARTED ──P1──▶ REVUE_BUSINESS ──P2──▶ CADRAGE_EN_COURS ──P3──▶ FABRICATION_MVP
                                                                       │
                                                                       ▼
                                                      REVUE_MVP ──P10──▶ TERMINE
                                                           ├─────────▶ PERSEVERE ──▶ (nouveau cycle)
                                                           └─────────▶ PIVOTED
       BLOCKED et ARCHIVED accessibles depuis la plupart des statuts intermédiaires.

Feature — 8 statuts

NOT_STARTED ──P4──▶ ANALYSE ──P4-DOR──▶ PRET_FABRICATION ──Sprint──▶ FABRICATION
                                                                         │
                                                                         ▼
                                                           VALIDATION ──P8──▶ PRET_LIVRAISON
                                                                                   │
                                                                                   ▼
                                                                       DEPLOIEMENT ──P9──▶ LIVRE

Récit — 8 statuts

NOT_STARTED ──P5-start──▶ AFFINAGE ──P5-DOR──▶ PRET_DOR ──▶ DEV ──P6-PR──▶ DEV_TERMINE
                                                                                   │
                                                                                   ▼ Démo PO
                                                                       VALIDATION ──P6-DoD──▶ VALIDE
                                                                              │
                                                                              └───▶ DEV (defect)

La liste complète se trouve en annexe. Les transitions sont définies dans schema.js:TRANSITIONS (lignes 105-536). Chaque entrée a la forme :

{
  gate:          "P4-DOR — DOR Feature",
  preconditions: [ ... liste humaine ... ],   // checklist affichée au move
  freeze:        [ ... ],                     // libellés des artefacts gelés
  invariants:    [ { kind, id, ...params } ], // vérifications parent-enfant
  checks:        [ { kind, id, path, ... } ], // vérifications fichiers
}

5. Portes et verdicts

Une transition est évaluée en trois temps par evaluator.js:evaluateGate :

  1. Construire le contexte (buildContext) : résoudre parent et enfants dans le registre.
  2. Exécuter les invariants puis les checks dans l'ordre, chacun via son validateur (runOne).
  3. Agréger les résultats et calculer un verdict (computeVerdict).

Règle de verdict

CompositionVerdictEffet sur move
0 fail, 0 warnGOChecklist humaine puis transition.
0 fail, ≥ 1 warnNEEDS-REVIEWChecklist humaine avec prompt d'arbitrage explicite.
≥ 1 failNO-GORefus, sauf --force (tracé dans l'historique).

État de couverture (après vague 3)

EntitéPortes automatiséesPortes encore descriptives
BEP2, P3, P10 3P1, P10-term/persévère/pivot, blocages, archives (15)
FEP4, P4-DOR, P7, P8, P9-init, P9-term 6Sprint-start, archives (3)
USP5-start, P5-DOR, sprint-dev, P6-PR, P6-DoD 5PO-demo, defect, archives (4)

14 / 42 portes automatisées à ce jour.

Observation (description, pas correction)

Le vocabulaire des portes (P1 → P10) et des prérequis reflète une gouvernance de grande entreprise (COMEX, homologation, PI planning). Ce lexique est hérité et apparaît en clair dans schema.js et dans les preconditions. Voir §10 — Perspectives.

6. La bibliothèque de validateurs

Les validateurs sont des fonctions pures (spec, ctx) → CheckResult. Ils ne mutent rien, ne font pas d'appel réseau, lisent uniquement le système de fichiers. Ils sont enregistrés dans l'objet VALIDATORS (validators.js:246).

Checks fichier

KindParamètresRôle
fileExistspathLe fichier existe au chemin interpolé.
fileNotEmptypath, minBytes?Le fichier fait ≥ N octets.
fileContainspath, pattern, flags?Le contenu match une regex.

Checks frontmatter (YAML en tête de fichier)

KindParamètresRôle
frontmatterHaspath, keys[]Toutes les clés présentes et non vides.
frontmatterInpath, key, allowed[]Valeur dans une liste close.
frontmatterRegexpath, key, patternValeur match une regex (ex. ^\d+$).

Invariants parent-enfant

KindParamètresRôle
parentExists—L'objet a bien un parent référencé.
parentStatusInallowed[]Le parent est dans un statut compatible.
allChildrenStatusInallowed[]Tous les enfants sont dans la liste (warn si 0 enfant).
anyChildStatusInallowed[]Au moins un enfant satisfait.
noChildInStatusforbidden[]Aucun enfant dans les statuts interdits.
minChildCountminAu moins N enfants.

Deux utilitaires clés

  • interpolate(template, obj) — substitue {id}, {type}… dans un chemin, l'id étant forcé en minuscule.
  • safeResolve(projectRoot, relPath) — résout un chemin relatif et renvoie { abs, inside, relPath }. Depuis la vague 3, un chemin hors projet ne jette plus d'erreur : les validateurs retournent warn (verdict NEEDS-REVIEW), l'humain arbitre via move --force.

7. CLI et registre

sdlc/sdlc.js est le seul mutateur d'état autorisé. Toute modification directe de sdlc-registry.json est une violation (le hook git pre-commit détecte les incohérences).

Commandes

CommandeEffet
statusTableau de bord : tous les objets du registre, regroupés par type, avec statut, porte, heat.
init <type> <id> <titre> [--parent X]Crée un objet en NOT_STARTED. Refuse si parent absent / mauvais type / terminal.
check <id>Liste les transitions possibles depuis le statut courant ; affiche pour chacune prérequis, artefacts à geler, et évaluation automatisée avec verdict.
move <id> <statut> [--force] [--message "..."] [--no-git]Transitionne : évalue la porte, demande confirmation interactive de la checklist humaine (sauf --force), met à jour le registre, écrit l'événement, commite.
log <id>Historique chronologique des transitions d'un objet, avec notes et artefacts gelés.
validateVérifie la cohérence globale : types, statuts, filiation, alignement meta_status.

Traces persistées

.product/
├── sdlc-registry.json              état courant + history[] par objet
└── .events/
    └── YYYY-MM-DD-sdlc-<id>-<to>.md   un fichier par transition, commité

Chaque entrée d'history contient : from, to, date, gate, message, frozen[], forced, et — si la porte était automatisée — un checks_snapshot[] complet avec le verdict.

Propriété recherchée : auditabilité totale

À tout moment on peut rejouer la logique : sdlc-registry.json donne l'état, les commits donnent la chronologie, les événements donnent le détail narratif. Rien n'est effacé, seulement gelé.

8. La boucle IA / déterministe

Le kernel orchestre deux régimes de travail qui ne se remplacent pas :

┌──────────────── DÉTERMINISTE ─────────────────┐
│  sdlc.js (état)   schema.js (forme)           │
│  evaluator.js (verdict)  hooks (rituels)      │
│                                               │
│   · impose la forme                           │
│   · garde la mémoire                          │
│   · bloque si incohérence                     │
└────────────────────┬──────────────────────────┘
                     │  fournit le contexte
                     ▼
┌──────────────── GÉNÉRATIF (IA) ───────────────┐
│  coach-emergent (orchestrateur)               │
│  16 #assistants (producteurs d'artefacts)     │
│                                               │
│   · explore le besoin                         │
│   · rédige l'artefact LIVING                  │
│   · ne fait JAMAIS avancer un état            │
└───────────────────────────────────────────────┘

Conséquence pratique : l'IA écrit dans les fichiers .md du projet (EHS, LBC, story…). Le CLI lit ces fichiers via les validateurs, calcule un verdict, et seul un humain décide de faire bouger le statut.

Ce partage est intentionnel. La génération rapide par l'IA crée la matière de l'hypothèse ; la machine d'états crée la forme de la décision. L'un sans l'autre, ça dérape vers soit un bureaucratie sans substance, soit un flot d'idées sans traçabilité.

9. Lecture pour audit et conformité

Cette section est un parcours de revue. Chaque étape identifie un fichier, ce qu'on y cherche, et un critère de conformité.

1
Vocabulaire du domaine → sdlc/schema.js

Lire META (ligne 23), TYPES (32), STATES (46). Critère : les termes utilisés sont compréhensibles sans jargon d'entreprise, ou explicitement documentés dans SDLC.md.

2
Graphe des transitions → schema.js:TRANSITIONS (ligne 105)

Vérifier que chaque arête a un gate, des preconditions et — si la porte est critique — des checks ou invariants. Critère : aucune transition n'a de prérequis humain vide qui masque une vraie exigence.

3
Validateurs → sdlc/validators.js

Chaque validateur est pur (pas de mutation, pas de réseau, fs en lecture seule). Critère : signature homogène (spec, ctx) → CheckResult ; enregistrement unique dans VALIDATORS (ligne 246) ; pas d'exception non attrapée qui remonterait en NO-GO trompeur.

4
Règle de verdict → sdlc/evaluator.js:computeVerdict (ligne 71)

Trois branches : fail > 0 → NO-GO, warn > 0 → NEEDS-REVIEW, sinon GO. Critère : la priorité fail > warn > pass est explicite et testée (evaluator.test.js lignes 18-26).

5
Seul mutateur d'état → sdlc/sdlc.js:cmdMove (ligne 358) et executeTransition (450)

Toute écriture dans sdlc-registry.json passe par saveRegistry. Critère : aucune autre partie du code n'écrit ce fichier ; l'--force est tracé dans history[].forced = true.

6
Filiation → sdlc.js:PARENT_RULES (ligne 276) et cmdValidate (553)

Critère : FE exige un parent BE, US exige un parent FE ; un parent en statut terminal est refusé. validate rejoue ces règles sur tout le registre.

7
Traçabilité → sdlc.js:executeTransition (ligne 450) + writeEvent (509)

Chaque transition produit (a) une entrée history, (b) un fichier .product/.events/*.md, (c) un commit git. Critère : les trois sont alignés et reproductibles.

8
Couverture des tests → sdlc/__tests__/

node --test sdlc/__tests__/*.test.js doit passer à vert (58 tests actuellement). Critère : chaque porte automatisée a au moins un test NO-GO et un test GO ; le chemin hors projet donne NEEDS-REVIEW.

9
Hook git → sdlc/install-hooks.js

Critère : le hook pre-commit refuse un registre incohérent ; l'installation est idempotente.

10
Absence de dépendance externe → racine du repo

Critère : pas de package.json avec dépendances runtime ; le kernel tourne avec Node ≥ 18 standard. Zéro surface d'attaque supply-chain, zéro node_modules.

10. Perspectives — ce qu'on observe, sans rien changer

Cette section décrit les tensions visibles dans le code tel qu'il est. Elle ne propose pas de correction ; elle rend lisible ce que le modèle actuel fait vivre.

10.1 — Héritage lexical d'une gouvernance d'entreprise

Les portes s'appellent P1 à P10, avec des prérequis comme « Décision COMEX tracée », « Enveloppe budgétaire confirmée par sponsor », « PI planning », « accord homologation ». Ce vocabulaire suppose un contexte d'organisation structuré (sponsor, COMEX, filière pilote, architecture d'entreprise). Dans un contexte différent — équipe autonome, produit émergent, cycle court — certaines portes sont vides de sens, d'autres manquent.

10.2 — Granularité fixe BE / FE / US

La hiérarchie est imposée à 3 niveaux obligatoires avec filiation stricte (PARENT_RULES). Pour un produit naissant où la valeur n'est pas encore découpée en PIs, cette structure force un habillage artificiel. À l'inverse, pour un système complexe, elle peut être trop plate (pas de notion de composant, de capability, de thème).

10.3 — 10 portes, ~42 transitions, 14 automatisées

Le ratio est significatif : un tiers des portes sont réellement exécutables. Les deux autres tiers sont des checklists humaines, utiles pour guider mais sans garde-fou machine. Ce déséquilibre reflète une hypothèse implicite : la plupart des décisions ne sont pas mécanisables. C'est peut-être vrai, peut-être le signe qu'il manque des invariants encore non formulés.

10.4 — Tension entre « minimal utile » et « 10 portes »

L'intention du système est d'aboutir vite à une solution minimale utilisable. Le chemin le plus court dans la machine d'états pour livrer une FE est :
BE.NOT_STARTED → REVUE_BUSINESS → CADRAGE_EN_COURS → FABRICATION_MVP
puis pour une FE : NOT_STARTED → ANALYSE → PRET_FABRICATION → FABRICATION → VALIDATION → PRET_LIVRAISON → DEPLOIEMENT → LIVRE,
soit 10+ transitions humaines avant un premier déploiement. La rapidité recherchée est donc pour l'instant tributaire de la discipline humaine à ne pas sur-instrumenter les premières itérations.

10.5 — L'IA produit, l'humain décide, mais le modèle du besoin est à l'humain

Les assistants IA (16 prompts spécialisés) couvrent la production (rédiger une EHS, découper en features, écrire une story TDD). Aucun n'est chargé de remettre en cause l'hypothèse, de proposer un grain différent, ou de détecter une incohérence épistémique. La boucle herméneutique — lecture du besoin qui modifie la compréhension du besoin — repose entièrement sur l'humain et sur le Coach.

10.6 — COLD irréversible, donc tout nouveau cycle est coûteux

La règle LIVING/COLD est forte : un artefact gelé ne se modifie pas. Si la compréhension du besoin change, il faut ouvrir un nouveau grain (pivot, persévère, nouvelle BE). Cela protège la traçabilité, mais rend chaque pivot coûteux en fichiers, en références, en registre. Un mode fork d'artefact ou un mécanisme de cycle N+1 explicite n'existe pas aujourd'hui ailleurs que dans la transition REVUE_MVP → PERSEVERE → FABRICATION_MVP.

Observation de synthèse

Le kernel actuel est un outil solide de gouvernance déterministe greffé sur un atelier IA de production d'artefacts. Sa forme reflète une organisation d'entreprise structurée. Son intention (génératif, herméneutique, minimal utile) est plus ambitieuse que ce que la forme actuelle facilite. Cette section ne conclut rien, elle constate.

Annexe A — Fichiers du kernel

FichierLOCRôle
sdlc/schema.js559SSOT : META, TYPES, STATES, TRANSITIONS + helpers.
sdlc/validators.js27912 validateurs purs + interpolate et safeResolve.
sdlc/evaluator.js117Moteur de verdict evaluateGate + buildContext.
sdlc/sdlc.js658CLI, seul mutateur ; commandes status, init, check, move, log, validate.
sdlc/frontmatter.js—Parser YAML minimal (scalaires, listes inline, objets).
sdlc/install-hooks.js—Installe .git/hooks/pre-commit (cohérence registre).
sdlc/SDLC.md—Documentation humaine de la machine d'états.
sdlc/__tests__/validators.test.js—22 tests validateurs.
sdlc/__tests__/evaluator.test.js—29 tests évaluateur + portes.
sdlc/__tests__/frontmatter.test.js—7 tests parser.

Annexe B — Toutes les transitions

BE — Business Epic

DeVersPorteAuto
NOT_STARTEDREVUE_BUSINESSP1 — Réception EOhumain
NOT_STARTEDARCHIVEDDéprioritisation portfoliohumain
REVUE_BUSINESSCADRAGE_EN_COURSP2 — GO Cadrage (COMEX)checks
REVUE_BUSINESSBLOCKED / ARCHIVEDBlocage / NO-GO Cadragehumain
CADRAGE_EN_COURSFABRICATION_MVPP3 — GO Fabricationchecks
CADRAGE_EN_COURSBLOCKED / ARCHIVEDBlocage / NO-GO Fabricationhumain
FABRICATION_MVPREVUE_MVPP10 — Fin MVPinv+checks
FABRICATION_MVPBLOCKED / ARCHIVEDBlocage / Abandon MVPhumain
REVUE_MVPTERMINE / PERSEVERE / PIVOTED / ARCHIVEDP10 — Décision terminalehumain
PERSEVEREFABRICATION_MVPRelancement cycle MVPhumain
BLOCKED(retour 3 statuts) / ARCHIVEDDéblocagehumain

FE — Feature

DeVersPorteAuto
NOT_STARTEDANALYSEP4 — Engagement PI Planninginvariants
NOT_STARTEDARCHIVEDDéprioritisation backloghumain
ANALYSEPRET_FABRICATIONP4-DOR — DOR Featureinv+checks
ANALYSEARCHIVEDDéprioritisation en analysehumain
PRET_FABRICATIONFABRICATIONSprint Starthumain
FABRICATIONVALIDATIONP7 — Validation intégrationinvariants
VALIDATIONPRET_LIVRAISONP8 — Homologationchecks
PRET_LIVRAISONDEPLOIEMENTP9-init — Déploiement initiéchecks
DEPLOIEMENTLIVREP9-term — Feature livréeinv+checks

US — Récit

DeVersPorteAuto
NOT_STARTEDAFFINAGEP5-start — Entrée sprint backloginvariants
NOT_STARTEDARCHIVEDArchivage backloghumain
AFFINAGEPRET_DORP5-DOR — DOR Récitinv+checks
AFFINAGEARCHIVEDRécit refusé en affinagehumain
PRET_DORDEVSprint — Dev startinvariants
DEVDEV_TERMINEP6-PR — PR mergéinv+checks
DEV_TERMINEVALIDATIONDémo POhumain
VALIDATIONVALIDEP6-DoD — DoD Récitchecks
VALIDATIONDEVRetour dev (defect)humain