Skip to content
CYPT71 edited this page Aug 19, 2026 · 2 revisions

TODO consolidé — Platform Factory Next Gen

État consolidé : 9 août 2026

Règles de validation

Une tâche n’est [x] que si :

  • l’implémentation existe réellement ;
  • elle est câblée dans un chemin produit réel lorsqu’un câblage est requis ;
  • elle possède des tests adaptés ;
  • la CI exécute le chemin concerné ;
  • une capacité déclarée est effectivement démontrée ;
  • retry/crash ne peut pas créer silencieusement un état incohérent.

P0 — Stabilisation immédiate

1. Baseline et toolchain

  • Nettoyer complètement l’arbre Git.
  • Créer une baseline de stabilisation.
  • Verrouiller Go sur 1.25.12.
  • Fournir make bootstrap.
  • Fournir make verify.
  • Fournir make release-check.
  • Utiliser GOTOOLCHAIN=local.
  • Séparer l’installateur TUI dans son propre module.
  • Définir et documenter la politique de mise à jour de Go.
  • Décider s’il existe une version Go minimale distincte et la tester.

2. Périmètre stable

Définir comme parcours stable prioritaire :

source
→ pf init
→ pf build
→ OCI reproductible
→ SBOM / provenance / signature
→ Registry
→ Kubernetes container
  • Publier une matrice de maturité.
  • Publier une matrice de compatibilité.
  • Transformer cette matrice en véritable contrat de support de release.
  • Maintenir explicitement les fonctions non suffisamment éprouvées en experimental/beta.
  • Définir précisément les critères Experimental, Supported, Stable.
  • Geler temporairement l’ajout de nouveaux sous-systèmes jusqu’à fermeture des P0.

P0 — Core Next Gen

3. Modèle canonique

  • Introduire les premiers types centraux dans internal/core.
  • Finaliser les objets canoniques :
WorkloadID
OperationID
ArtifactDigest
PluginID

WorkloadSpec
BuildPlan
ArtifactDescriptor
RuntimeSpec
DeploymentSpec
RuntimeState
EvidenceBundle
CapabilitySet
PolicyDecision

Pour chacun :

  • version de schéma ;
  • validation stricte ;
  • sérialisation canonique ;
  • sérialisation déterministe ;
  • politique de migration ;
  • comportement explicite face aux champs inconnus ;
  • digest lorsque pertinent.

4. Machine à états

  • Implémenter la machine à états canonique.
  • Définir les transitions nominales.
  • Définir l’idempotence des transitions.
  • Documenter les compensations nécessaires.
  • Câbler réellement la machine à états dans les parcours produit. internal/app/publish.TransitionWorkload appelle RuntimeState.TransitionTo (le vrai code de transition, pas un doublon) et est appelé depuis cmd/platform-factory/lifecycle.go pour PhasePublishing/PhasePublished/PhaseFailed sur le chemin publish réel - seul appelant hors tests de TransitionTo dans tout le dépôt. Le mapping containerd/Kubernetes/KubeVirt ci-dessous reste à faire.
  • Mapper l’état containerd vers RuntimeState.
  • Mapper l’état Kubernetes vers RuntimeState.
  • Mapper l’état KubeVirt vers RuntimeState.
  • Définir explicitement DesiredState.
  • Définir explicitement ObservedState.
  • Définir explicitement OperationJournal.
  • Ajouter la réconciliation après divergence/crash.
  • Tester les transitions avec perte de réponse et état externe préexistant.

P0 — Architecture du code

5. Couche applicative

Déplacer progressivement la logique de :

cmd/platform-factory

vers :

internal/app/init
internal/app/build
internal/app/publish
internal/app/deploy
internal/app/runtime
internal/app/verify

État :

  • doctor.
  • sbom.
  • verify-release.
  • Renommer/normaliser définitivement internal/app/releaseinternal/app/verify si nécessaire. internal/app/release n'existe plus ; internal/app/verify existe et est câblé (verify-release).
  • Extraire init. Câblé sous le nom internal/app/projectinit (pas internal/app/init) ; cmd/platform-factory/init.go délègue explicitement (« runInit is the CLI adapter for internal/app/projectinit »).
  • Extraire build. internal/app/build existe, câblé depuis cmd/platform-factory/project.go/main.go.
  • Extraire publish. internal/app/publish existe, câblé depuis cmd/platform-factory/lifecycle.go.
  • Extraire deploy. internal/app/deploy existe, câblé depuis cmd/platform-factory/lifecycle.go.
  • Extraire runtime. Pas de paquet internal/app/runtime unique ; les préoccupations runtime sont réparties entre internal/app/microvm et internal/app/observe (câblés depuis lifecycle.go/microvm.go/ observe.go) - à normaliser ou à documenter comme découpage définitif.
  • Extraire les parcours pipeline encore détenus par la CLI. internal/app/pipeline existe, câblé depuis cmd/platform-factory/evidence.go et pipeline.go.

La CLI finale doit seulement :

  1. parser ;
  2. charger ;
  3. appeler un service ;
  4. formater ;
  5. traduire l’erreur en code de sortie.

6. Frontières d’architecture

  • Ajouter un test automatique d’architecture.
  • Découpler sdk/oci de internal/oci.
  • Découpler sdk/pipeline de internal/pipeline.
  • Découpler internal/policy de internal/plugin.
  • Découpler internal/executor de internal/cache.
  • Découpler internal/executor de internal/networking.
  • Découpler internal/assemble de internal/cache.
  • Supprimer internal/assemble → internal/oci. Aucun import internal/oci/oci restant dans internal/assemble ; interdit explicitement par internal/archtest's domainInfrastructureBoundaries.
  • Supprimer internal/project → internal/oci. Idem : aucun import restant, interdit explicitement par internal/archtest.
  • Classifier explicitement les dépendances internal/* → api/v1* comme autorisées ou interdites. Non couvert par domainInfrastructureBoundaries à ce jour.
  • Faire échouer CI sur toute nouvelle violation. internal/archtest.CheckForbiddenImports est appelé depuis internal/archtest/archtest_test.go, donc exécuté par tout go test ./... (ci-quality.yml, ci-security.yml) - une nouvelle violation fait échouer le test, pas seulement les deux règles ci-dessus.

Architecture cible :

cmd
 ↓
app
 ↓
domain/core
 ↓
interfaces
 ↑
implementations/adapters

Le Core ne doit jamais connaître directement :

Kubernetes
containerd
KubeVirt
Docker
Podman
backend VMM concret

P0 — Plugins

7. Familles et capacités

  • Définir LanguagePlugin.
  • Définir AnalyzerPlugin.
  • Définir BuildPlugin.
  • Définir RuntimePlugin.
  • Définir DeploymentPlugin.
  • Définir CapabilityPlugin.
  • Définir le manifeste canonique.
  • Supporter la dot-notation des capacités.
  • Ajouter PluginRegistry.
  • Indexer par capacité.
  • Indexer par famille.
  • Ajouter la découverte et l’enregistrement.
  • Ajouter les manifests containerd/KubeVirt/lang-go.
  • Vérifier les capacités depuis le client.
  • Remplacer les derniers dispatchs fondés sur l’identité du backend par des requêtes de capacités.
  • Ajouter les manifests à tous les plugins officiellement livrés.
  • Tester la négociation de bout en bout depuis une vraie commande CLI.

Principe :

NON : "Es-tu KubeVirt ?"

OUI : "Fournis-tu deployment.apply
       pour cette plateforme et ces contraintes ?"

8. Idempotence

  • Définir OperationID.
  • Implémenter un journal mémoire.
  • Implémenter un journal plugin durable.
  • Ajouter un claim inter-processus atomique.
  • Ajouter CallWithIdempotency.
  • Refuser les collisions de digest.
  • Traiter les réponses perdues comme état indéterminé.
  • Tester la concurrence.
  • Tester la persistance entre instances.
  • Câbler OperationID dans publish.
  • Câbler OperationID dans deploy.
  • Câbler OperationID dans toutes les mutations runtime.
  • Ajouter une persistance durable générique hors appels plugin.
  • Tester crash après mutation mais avant confirmation.
  • Tester redémarrage puis reprise.
  • Tester suppression partielle.
  • Tester état distant existant / état local absent.

9. Trust, signature et provenance plugin

  • Vérifier le digest.
  • Vérifier la signature Ed25519.
  • Vérifier l’identité.
  • Vérifier le protocole attendu.
  • Ajouter la révocation par clé.
  • Ajouter la révocation par digest.
  • Refuser avant démarrage un plugin révoqué.
  • Ajouter une provenance de build vérifiable du plugin. internal/provenance/plugin.go's PluginBuildInputs/ GeneratePluginProvenance, câblé depuis cmd/platform-factory/plugin_provenance.go - le commentaire du code cite explicitement cet item de checklist par son nom.
  • Associer source + builder + artefact + digest. PluginBuildInputs : SourceCommit/SourceDirty, BuilderID + GoVersion, ArtifactDigest (sha256, même format que Manifest.Digest).
  • Définir une politique de confiance organisationnelle.
  • Définir rotation et révocation opérationnelles.

10. Sandbox par niveau de risque

  • Interdire le réseau aux plugins language.
  • Isolation Linux générique existante.
  • Formaliser un PermissionProfile par famille. internal/plugin/permission_profile.go : une entrée par PluginFamily (Language/Analyzer/Build/Runtime/Deployment/Capability), seuils choisis à partir de mesures réelles documentées (pas devinés), câblé dans sandbox_linux.go/client.go.
  • Limiter CPU par manifeste/politique. PermissionProfile.CPUSeconds (RLIMIT_CPU), par famille.
  • Limiter mémoire avec un mécanisme compatible avec les runtimes. PermissionProfile.MemoryMiB (RLIMIT_AS), seuils re-vérifiés stables empiriquement par famille (voir le commentaire du type).
  • Limiter PIDs. PermissionProfile.Processes (RLIMIT_NPROC), par famille.
  • Isoler le répertoire temporaire. isolateTempDirectory() donne au plugin son propre tmpfs privé exposé via $TMPDIR, appelée dans le chemin de sandboxing réel.
  • Limiter précisément le workspace accessible.
  • Pour containerd : autoriser explicitement uniquement le socket requis.
  • Pour KubeVirt : RBAC minimal. RBAC() (plugins/kubevirt/kubevirt.go) rend un ServiceAccount/Role/RoleBinding minimal.
  • Pour KubeVirt : namespace borné. Le même code lie explicitement à un Role (jamais un ClusterRole) scopé à s.Namespace.
  • Interdire les credentials cluster-admin. Même mécanisme : jamais de ClusterRole, donc jamais d'accès cluster-admin par construction.
  • Tester chaque profil avec un plugin hostile. internal/plugin/hostile_plugin_test.go : TestHostileMemoryBombIsBlockedByRLIMIT_AS, TestHostileForkBombIsBoundedByRLIMIT_NPROC - preuves réelles contre les limites PermissionProfile ci-dessus, pas une assertion de configuration.

P0 — Erreurs et observabilité

11. Taxonomie d’erreurs

  • Erreurs typées.
  • Codes catégorisés.
  • Retryable(err).
  • ExitCode(err).
  • trace_id dans les erreurs.
  • Sérialisation JSON.
  • Migrer les derniers composants encore sur des erreurs non typées.
  • Supprimer les mappings de code de sortie codés en dur dans les handlers CLI.
  • Utiliser systématiquement le mapping central.

Codes cibles :

0  success
2  invalid input
3  unsupported
4  policy denied
5  conflict
6  dependency unavailable
7  timeout
8  corruption
10 internal error

12. Trace et corrélation

  • Génération robuste de trace_id.
  • Propagation CLI.
  • Propagation build.
  • Propagation publish.
  • Propagation deploy.
  • Propagation protocole plugin.
  • Logs structurés avec trace_id.
  • Généraliser operation_id aux mêmes frontières.
  • Ajouter workload_id.
  • Ajouter build_id.
  • Ajouter pipeline_id.
  • Ajouter stage_id.
  • Propager la corrélation jusqu’aux preuves et au journal d’opérations.

P0 — Fiabilité des ressources

13. Budgets

  • Budget wall-clock pipeline.
  • Budget OCI in-process.
  • Mesure CPU/RSS réelle d’un processus enfant.
  • Câbler budget.FromProcessState dans internal/executor.Executor.Run.
  • Agréger CPU par stage.
  • Agréger mémoire par stage.
  • Agréger les consommations au niveau pipeline.
  • Exposer les dépassements comme erreurs typées.
  • Ajouter métriques et événements associés.

P0 — Parcours produit

14. pf init

pf init doit suivre :

détecter
→ proposer
→ expliquer
→ confirmer
→ écrire
  • Détecter les composants.
  • Détecter les langages.
  • Détecter les commandes de build.
  • Détecter les artefacts.
  • Détecter ports et variables.
  • Détecter les ressources externes probables.
  • Signaler les incertitudes.
  • Demander explicitement ce qui ne peut pas être prouvé.
  • Générer platform-factory.yaml.
  • Générer le lock associé.
  • Supporter les projets multi-composants.
  • Supporter lifecycle: external.
  • Supporter lifecycle: shared.
  • Enregistrer explicitement le choix container/MicroVM et ses raisons.

pf init ne doit ni construire ni déployer.

15. pf build

  • OCI déterministe/reproductible.
  • Multi-architecture.
  • SBOM.
  • Provenance.
  • Signature.
  • Consommer exclusivement le projet validé issu de init.
  • Ne plus refaire silencieusement les décisions d’init.
  • Refuser toute ambiguïté non résolue.
  • Produire un EvidenceBundle canonique.
  • Associer tous les artefacts à leurs digests.

16. pf publish

  • Client Registry natif.
  • Upload reprenable.
  • Vérification des digests.
  • Publication avec preuves.
  • Ajouter OperationID au parcours réel.
  • Produire un plan/diff avant mutation.
  • Référencer les workloads par digest immuable.
  • Déployer via capacité et non identité de backend.
  • Suivre le rollout.
  • Journaliser chaque mutation.
  • Fournir rollback/reconciliation.
  • Garantir qu’une ressource external/shared ne puisse être supprimée accidentellement.

P1 — Tests de stabilité

17. E2E canoniques

Faire tourner quotidiennement au minimum :

  • Go → OCI → Registry.
  • Python plugin → OCI → Kubernetes.
  • OCI MicroVM → runtime réel.

Chaque scénario doit vérifier :

  • digest ;
  • preuves ;
  • état final ;
  • logs corrélables ;
  • cleanup ;
  • retry ;
  • reprise.

18. Tests de panne

Ajouter des scénarios automatisés pour :

  • kill builder ;
  • kill plugin ;
  • kill VMM ;
  • kill worker ;
  • restart control plane ;
  • restart containerd ;
  • Kubernetes indisponible ;
  • Registry indisponible ;
  • réseau interrompu pendant upload ;
  • offset Registry incorrect ;
  • réponse plugin tronquée ;
  • disque plein ;
  • mémoire insuffisante ;
  • corruption CAS ;
  • suppression interrompue ;
  • publication interrompue ;
  • déploiement interrompu ;
  • réponse perdue après mutation réussie.

Critère : après chaque panne, le système doit reprendre ou nettoyer, jamais simplement « échouer ».

19. Fuzzing

  • 24 cibles existantes (grep -rn '^func Fuzz' --include='*_test.go' - le chiffre a grossi depuis la rédaction initiale de cette liste).

  • Exécution hebdomadaire longue (ci-fuzz.yml, 10 min/cible le samedi 04:41 UTC, 45 s/cible sur push/PR).

  • Câbler les 5 cibles existantes mais non exécutées par ci-fuzz.yml : FuzzCapabilityResolutionEvidence, FuzzMigrationWireDiscovery, FuzzMigrationArtifactMetadata, FuzzCanonicalGraph, FuzzMigrationPlanYAML.

  • Conserver systématiquement les crashers.

  • Alimenter les corpus avec des cas réels/malveillants.

  • Prioriser les frontières encore sensibles :

    • plugin framing ;
    • OCI/tar ;
    • Registry ;
    • état/journal ;
    • protocoles host/guest ;
    • formats disque.

*(Corrigé en cours de revue : deux cibles de ci-fuzz.yml

  • FuzzLabelsFromPairs/FuzzEntrypointValidation - pointaient encore vers ./internal/ociruntime, un chemin issu du renommage internal/ocioci ; go test -fuzz sur un paquet ne contenant pas la cible nommée exécute silencieusement les tests normaux du paquet au lieu de fuzzer, donc ces deux frontières n'étaient en réalité pas fuzzées malgré un job vert. Corrigé.)*

20. Déterminisme

Tester le même input sur :

  • plusieurs machines ;
  • plusieurs chemins de workspace ;
  • plusieurs fuseaux horaires ;
  • locales différentes ;
  • UID/GID différents ;
  • ordre source différent.

Invariants :

digest A == digest B
plan A == plan B
manifest A == manifest B
evidence A référence exactement le même artefact

P1 — Sécurité

21. Threat model

  • Threat model global existant.
  • Builder OCI.
  • Sandbox.
  • Plugins.
  • Registry.
  • Publication.
  • MicroVM.
  • Scheduler distribué.
  • CAS.

Pour chaque frontière :

  • actifs ;
  • attaquants ;
  • données hostiles ;
  • TCB ;
  • hypothèses ;
  • risques résiduels ;
  • contrôles ;
  • tests ;
  • mapping STRIDE ou équivalent.

22. Audits indépendants

Priorité :

  • protocole/exécution plugin ;
  • extraction OCI/tar ;
  • sandbox ;
  • cryptographie/signature ;
  • client Registry ;
  • guest agent/VMM ;
  • formats disque.

Ne pas considérer un auto-audit comme une revue indépendante.


P1 — Gouvernance

23. Repository

  • Dépôt public.
  • CODEOWNERS.
  • Protéger main.
  • Interdire les push directs.
  • Exiger les checks CI.
  • Exiger les propriétaires sécurité pour les workflows critiques.
  • Protéger les tags.
  • Protéger l’environnement release.
  • Exiger une approbation de release.
  • Définir qui peut publier.
  • Documenter la révocation des accès.
  • Ajouter/compléter GOVERNANCE.md.
  • Ajouter/compléter MAINTAINERS.md.
  • Ajouter/compléter CONTRIBUTING.md.

P1 — Release

24. Release gate

  • make release-check.
  • verify-release.
  • SBOM.
  • provenance.
  • signatures.
  • Bloquer réellement la publication si la release matrix n’est pas verte.
  • Ajouter tests crash/recovery au gate approprié.
  • Ajouter migration N-1 → N.
  • Ajouter test rollback.
  • Publier limitations connues.
  • Publier support matrix de la version.
  • Définir release candidate.
  • Définir période de validation avant stable.
  • Documenter procédure de release compromise.
  • Documenter révocation/re-release.

P2 — CLI et UX

25. Surface CLI

Surface cible :

pf init
pf build
pf publish
pf doctor
pf verify
  • Déprécier plusieurs anciens alias.
  • Avertissements sur stderr.
  • Définir une date/version de suppression.
  • Réduire les alias restants.
  • Harmoniser les flags.
  • Stabiliser --format=json.
  • Stabiliser --format=text.
  • Ajouter --quiet.
  • Ajouter --verbose.
  • Ajouter --debug avec redaction.
  • Respecter NO_COLOR.
  • Tester Bash.
  • Tester Zsh.
  • Tester Fish.
  • Tester PowerShell.
  • Tester chemins Unicode.
  • Tester chemins avec espaces.
  • Tester sans TTY.

26. doctor

  • Hyperviseur.
  • Sandbox.
  • Docker.
  • Podman.
  • containerd.
  • Kubernetes.
  • Registry config.
  • Vérifier un RuntimeClass demandé.
  • Vérifier permissions réelles du runtime.
  • Vérifier authentification Registry contre une cible donnée.
  • Vérifier les capabilities nécessaires à un projet précis.

P2 — Documentation et exploitation

27. Documentation

  • Réduire le README à une vraie page d’accueil.
  • docs/architecture.
  • docs/security.
  • docs/reference.
  • docs/tutorials.
  • docs/operations.
  • docs/limitations.
  • Glossaire.
  • Index.
  • Guides de migration.
  • Troubleshooting.
  • Production readiness.
  • Support policy.
  • Compatibility policy.
  • Page « ce que Platform Factory ne protège pas ».

28. Runbooks

Créer au minimum :

  • build bloqué ;
  • plugin bloqué ;
  • workload orphelin ;
  • état divergent ;
  • publication Registry partielle ;
  • KubeVirt VMI inconnue ;
  • corruption CAS ;
  • restauration ;
  • rotation des clés ;
  • release compromise ;
  • rollback.

P2 — Observabilité opérationnelle

29. Journal d’opérations

Chaque mutation doit produire :

requested
planned
started
external_mutation
confirmed
completed
compensated
failed
  • Définir le schéma versionné.
  • Rendre l’écriture résistante aux crashes.
  • Ajouter operation_id.
  • Ajouter trace_id.
  • Ajouter workload_id.
  • Ajouter le digest de l’artefact.
  • Ajouter backend/capability.
  • Ajouter état avant/après.
  • Ajouter récupération/replay contrôlé.

30. SLO

Définir et mesurer :

  • taux de succès build ;
  • intégrité des artefacts publiés ;
  • ressources orphelines ;
  • temps de reprise après crash ;
  • mutations possédant un operation_id ;
  • erreurs Registry ;
  • retries ;
  • reprises d’upload ;
  • consommation sandbox ;
  • files scheduler.

P3 — VMM et distribution

Ne reprendre ces chantiers qu’après fermeture des principaux P0/P1.

31. VMM natif

  • Finaliser virtio réel.
  • KVM Linux complet.
  • HVF macOS complet.
  • backend Windows natif.
  • sandbox VMM démontrée sur matériel réel.
  • tests host/guest.
  • tests crash/recovery.
  • audit tiers.

32. Plateforme distribuée

  • Stabiliser control plane.
  • Stabiliser worker protocol.
  • Source de vérité durable.
  • Reconciliation.
  • Quotas.
  • Scheduling.
  • Perte worker.
  • Partition réseau.
  • Restart control plane.
  • HA.
  • Backup/restore.
  • Chaos tests.

Ordre d’exécution recommandé

  1. terminer assemble/project → internal/oci ;
  2. câbler la machine à états dans un vrai parcours runtime ;
  3. câbler OperationID dans publish puis deploy ;
  4. généraliser le journal durable des mutations ;
  5. terminer les profils de sandbox plugin ;
  6. terminer la provenance des plugins ;
  7. câbler budget.FromProcessState dans l’executor ;
  8. terminer l’extraction CLI → internal/app/* ;
  9. établir les trois E2E quotidiens ;
  10. ajouter les scénarios crash/recovery ;
  11. terminer les threat models ;
  12. commander les audits indépendants ;
  13. activer les protections de release ;
  14. seulement ensuite reprendre VMM/distributed.

Definition of Done globale

Une capacité Platform Factory n’est pas terminée parce qu’un package existe.

Elle est terminée lorsque :

implémentée
+ intégrée
+ testée
+ exécutée en CI
+ observable
+ récupérable après crash
+ documentée
+ compatible avec son niveau de maturité annoncé

Règle centrale

Avant d’ajouter une nouvelle fonctionnalité :

Est-ce qu’elle rend un parcours existant plus fiable, plus observable ou plus reproductible ?

Si non, elle attend.

Clone this wiki locally