Skip to main content
Welcome. This site supports keyboard navigation and screen readers. Press ? at any time for keyboard shortcuts. Press [ to focus the sidebar, ] to focus the content. High-contrast themes are available via the toolbar.
serard@dev00:~/cv

L'arsenal complet du genie logiciel applique au droit

Une fois qu'on accepte que law is code, toute la pyramide moderne du genie logiciel devient transposable. Pas comme metaphore — comme infrastructure concrete, deployable, auditable. Cette partie condense les outils que vingt ans de genie logiciel ont produits, et montre comment chacun d'eux change le droit quand on l'y applique. Chaque outil genere un cadre specifique de verification, pas une verite universelle : la pyramide des tests d'un cadre Law.France2026.Etalab n'est pas la meme que celle d'un cadre Law.France2026.LaQuadrature, parce que leurs auteurs n'ont pas les memes exigences politiques.

Pyramide des tests juridiques

La pyramide classique du logiciel se transpose structurellement :

                  +--------------------+
                  | E2E juridique      |   ~10-30
                  | (citoyen -> admin  |   (parcours complet)
                  | -> resultat)       |
                  +---------+----------+
              +-------------+---------------+
              |  Scenarises (Regime 3)      |   ~50-200
              |  Given/When/Then politiques |   (simulations what-if)
              +-------------+---------------+
        +-------------------+-------------------+
        |   Integration (Roslyn)                |   ~200-500
        |   compile complet + bridges           |   (coherence inter-cadres)
        +-------------------+-------------------+
   +------------------------+--------------------------+
   |   Unitaires (Regime 1)                            |   ~1 000-5 000
   |   + 1 test minimum par alinea                     |   (FrontierCrossingDetector pur
   |   + property-based (Regime 4)                     |    + property-based)
   +---------------------------------------------------+

La convention est stricte : un test minimum par alinea type — un cas conforme, un cas violant. Le Law.QualityGate (cf. Partie 11 — Law.QualityGate) exige cette couverture ou echoue. Un alinea sans test est un alinea mort — personne ne peut prouver qu'il sert a quelque chose.

Les tests E2E juridiques vont plus loin que les tests d'integration. Ils couvrent le parcours complet : cas Mathilde, diagnostic CIT001, attestation signee, soumission a un FakeCAF qui verifie l'attestation et accepte ou refuse selon les diagnostics types. Le FakeCAF est un hand-written fake (cf. le pattern du projet existant), remplacable plus tard par l'API reelle d'un service public sans changer une ligne du test.

Mutation testing du droit — Stryker.NET et la vivacite juridique

Le mutation testing est l'outil le plus sous-utilise du genie logiciel, et c'est peut-etre celui qui a le plus de sens pour le droit. Le principe : on injecte des mutations dans le code et on verifie qu'au moins un test les attrape. Si une mutation survit (aucun test ne la detecte), c'est une zone morte.

Transposee au droit type, chaque mutation a un sens politique precis :

Mutation injectee Consequence si non attrapee
MeasureKind.Privatisation vers MeasureKind.Nationalisation Aucun test ne distingue les deux regimes pour ce bien — zone morte
Retrait de [DemocraticProcedure] Aucun test ne verifie la procedure pour cet alinea — risque de regression
MinDurationDays: 30 vers 15 Aucun test ne depend de la duree minimale — seuil non couvert
[Status(Public)] vers [Status(Private)] sur un bien Aucun cas citoyen ne depend du statut public de ce bien — bien sans usagers
Retrait d'une [Frontier] Aucun test ne depend de cette frontiere — frontiere inutile ou non couverte

Le mutation score juridique devient une mesure de la vivacite du droit. Un article qui resiste a zero mutations est mort : personne n'en depend, il pourrait disparaitre sans consequence. Un article qui resiste a cinquante mutations est vivant : chaque detail compte pour quelqu'un. C'est une mesure infiniment plus exigeante que la couverture de code classique, qui ne mesure que "passe par la" sans verifier que le passage fait une difference.

Le Law.QualityGate impose un seuil minimum :

// Law.QualityGate configuration
// MinMutationScore = 0.85
// Un build dont le mutation score est inferieur a 85% echoue.

En dessous de quatre-vingt-cinq pour cent, le build echoue. C'est une mesure objective de qualite juridique — et le legislateur a un indicateur concret pour savoir si ses lois sont vivantes (testees, dependues, utilisees) ou mortes (votees, oubliees, jamais appliquees).

Loi-driven Requirements — le package Requirements reutilise

Le package Requirements existe deja dans l'ecosysteme FrenchExDev (cf. Feature Tracking). Il fournit les attributs [Epic], [Feature], [ForRequirement], [Verifies] et la mecanique de detection d'orphelins. On le reutilise tel quel pour le droit — pas un nouveau Requirements.Law.Dsl, simplement le meme package applique a un nouveau domaine.

[Epic("RightToHousing", PoliticalPriority = "Constitutional")]
public sealed class RightToHousingEpic : Epic
{
    [Feature("DALO", "Enforceable Right to Housing")]
    public sealed class EnforceableRightToHousing
        : Feature<EnforceableRightToHousing>
    {
        // Criteres d'acceptation politiques
        public abstract void AnyHomelessFamilyCanClaim();
        public abstract void MaxProcessingDelaySixMonths();
        public abstract void AppealBeforeAdministrativeCourt();
        public abstract void FinancialPenaltyIfNotRespected();
    }
}

// Lien Feature -> Articles juridiques
[Article("L300-1")]
[ForRequirement(typeof(EnforceableRightToHousing))]
public sealed class ArticleL300_1
{
    [Paragraph(1)]
    [Verifies(nameof(EnforceableRightToHousing.AnyHomelessFamilyCanClaim))]
    public void Recital1() { }
}

La commande dotnet law-quality-gate features-coverage exhibe les promesses politiques non tenues au compile-time :

Epic: RightToHousing
  ! Feature: UnconditionalEmergencyShelter (2/4 ACs implemented -- 50%)
    OK  ShelterEvenWithoutPapers     -> ArticleL345_2_2.Recital1
    OK  MaintainUntilDurableSolution -> ArticleL345_2_3.Recital1
    X   MaximumOvernightDelay        -> ORPHAN
    X   FamilyAccommodation          -> ORPHAN

Global coverage Housing : 78%  (gate: 95%)  FAILED

C'est un changement copernicien. Aujourd'hui on vote une loi en esperant qu'elle implemente les promesses politiques. Demain on prouve qu'elle les implemente — ou on detecte les promesses non tenues avant le vote, pas apres. L'orphelin n'est pas un bug logiciel : c'est une promesse politique non codifiee. Le compile error est l'avertissement citoyen.

CI/CD pipeline — treize etapes et trois approbations humaines

Le pipeline complet d'un cadre juridique suit treize etapes :

# Law.France2026.Etalab.Dsl CI (structure)
jobs:
  quality:
    steps:
      - Setup .NET, Restore, Build (--warnaserror)
      - Unit tests (1 test min par alinea)
      - Integration tests (Roslyn full compile)
      - Scenario tests (BDD politiques)
      - E2E tests (citoyen -> FakeCAF -> decision)
      - Law quality gate (--strict)
      - Mutation testing (--threshold-break 85)
      - Citizen regression tests (cas-types ne doivent pas casser)
      - Property tests (FsCheck)
      - Pack
      - Detect SemVer bump (--fail-on-undeclared-major)
      - Sign packages (X.509, only main branch)
      - Publish to lex.france.fr (gated for MAJOR bumps)

Le dernier point est le plus important politiquement : un MAJOR bump exige trois approbations humaines. Pas de loi qui casse le quotidien des citoyens sans audit humain. C'est le meme pattern que les environnements de production critiques en genie logiciel — les deploiements MAJOR sur les banques, les hopitaux, les centrales nucleaires exigent des approbations multiples. Le droit est au moins aussi critique.

Aucune loi ne peut etre publiee sans avoir passe tous les gates. C'est le passage de la legislation impulsive a la legislation testee — appliquer au droit ce qu'on applique au logiciel serieux depuis vingt ans.

Deploiement progressif — feature flags, canary releases, experimentations territoriales

Le deploiement progressif est un acquis du genie logiciel que le droit pratique deja sans le formaliser. Les experimentations territoriales (la loi sur le revenu de base testee en Seine-Saint-Denis, la loi sur les mobilites testee en Bretagne) sont des canary releases. Les lois votees mais non encore applicables sont des feature flags desactives. Le projet les formalise en attributs types :

// Feature flag juridique
[Article("L132-4")]
[FeatureFlag("WaterLaw2030.WithdrawalCeiling", DefaultEnabled = false)]
public sealed class ArticleL132_4 { /* ... */ }

// Rollout territorial
[Article("L132-4-bis")]
[ExperimentalIn(typeof(Spaces.Bretagne), Until = "2027-12-31")]
public sealed class ArticleL132_4_bis { /* ... */ }

// Canary release
[Article("L500-1")]
[CanaryRelease(Percentage = 5, RolloutStrategy = "RandomCitizen",
    StartedAt = "2026-04-01")]
public sealed class ArticleL500_1 { /* ... */ }

Le citoyen est prevenu quand il est dans le canary : son dotnet build lui dit vous etes dans le deploiement progressif de la loi X — vous pouvez opt-out. Pas de surprise, pas de vous etes cobaye sans le savoir. C'est ce qu'on fait deja en pratique pour les experimentations legislatives, mais formalise, computable, et transparent pour le destinataire.

Observabilite OpenTelemetry — anonymisee par construction

L'observabilite est indispensable pour que le legislateur mesure l'impact reel de ses lois. Mais elle est aussi dangereuse si elle collecte des donnees personnelles. Le projet tranche : OpenTelemetry anonymise, opt-in obligatoire, k-anonymity-50.

// Cote analyzer citoyen
LawTelemetry.RecordCounter("citizen_diagnostic_emitted",
    tags: new {
        DiagnosticCode = diag.Code,
        Article = diag.Article,
        CorpusVersion = corpusVersion
    });
// Pas d'envoi de l'identite du cas
// Pas d'envoi des circonstances specifiques
// Juste : tel article a ete appele, dans tel corpus

L'opt-in est configure dans MyCases/.config/telemetry.json. Le k-anonymity-50 signifie que les traces ne sont publiees que quand au moins cinquante cas similaires sont regroupes — aucun lien possible entre une trace individuelle et une identite. Le code source du collecteur est ouvert et auditable. C'est exactement ce que Tor Metrics fait pour Tor.

Cote legislateur, un dashboard Grafana repond aux questions : combien de cas activent l'article L262-9 par semaine ? Quels articles generent le plus de violations CIT003 ? Pour la premiere fois, le legislateur peut mesurer l'impact reel de ses lois sans surveillance individuelle. C'est l'OpenTelemetry du droit — l'oppose exact de la surveillance de masse.

HA registre — le modele DNS root

Le compilateur tourne localement — il n'a pas besoin d'etre HA. Mais le registre doit l'etre. Le modele s'inspire du DNS root :

Composant Modele Responsabilite
Root authority Etalab / DINUM Signe avec cle X.509 (HSM hors-ligne)
Mirrors geographiques 8-12 universites (Renater) Servent les .nupkg signes
Mirrors associatifs LaQuadrature, Framasoft Idem
Mirrors P2P IPFS, BitTorrent DHT Distribution resiliente, identifiee par hash
Caches client ~/.nuget/packages/ local Vit indefiniment une fois telecharge

SLA cible : 99.99% pour le registre canonique, 99.999% agregee (au moins un mirror parmi N), propagation inferieure a cinq minutes pour 95% des mirrors. En cas de defaillance totale, IPFS prend le relais — les hash sont les memes, la verification X.509 est la meme.

Pile entierement OSS — aucun verrou proprietaire

L'ensemble de la chaine, du dotnet build au dotnet publish, est libre :

Composant Licence
C# language spec ECMA-334 (standard international)
.NET runtime + SDK MIT (.NET Foundation)
Roslyn (compiler + analyzers) MIT (code source public)
MSBuild MIT
NuGet client + protocol Apache 2.0 (multiples implementations serveur : BaGet, ProGet, Sleet)
Stryker.NET Apache 2.0
OpenTelemetry Apache 2.0 (standard CNCF)
VSCodium MIT (build OSS pur de VS Code)

Un Etat ou consortium souverain peut auto-heberger entierement sans rien demander a Microsoft. La dependance Microsoft est en realite une dependance a des standards qu'ils ont contribue a liberer — analogue a la dependance Python a Guido, ou Linux a Linus. Le .csproj est un format XML documente ; le protocole NuGet V3 est une API REST publique ; le compilateur Roslyn est MIT et forkable. Rien n'est verrouille, rien n'est captif, tout est reproductible.

⬇ Download