-
Notifications
You must be signed in to change notification settings - Fork 0
Todo
État consolidé : 9 août 2026
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.
- 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.
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.
- 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.
- 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.TransitionWorkloadappelleRuntimeState.TransitionTo(le vrai code de transition, pas un doublon) et est appelé depuiscmd/platform-factory/lifecycle.gopourPhasePublishing/PhasePublished/PhaseFailedsur le cheminpublishréel - seul appelant hors tests deTransitionTodans 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.
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/release→internal/app/verifysi nécessaire.internal/app/releasen'existe plus ;internal/app/verifyexiste et est câblé (verify-release). - Extraire
init. Câblé sous le nominternal/app/projectinit(pasinternal/app/init) ;cmd/platform-factory/init.godélègue explicitement (« runInit is the CLI adapter for internal/app/projectinit »). - Extraire
build.internal/app/buildexiste, câblé depuiscmd/platform-factory/project.go/main.go. - Extraire
publish.internal/app/publishexiste, câblé depuiscmd/platform-factory/lifecycle.go. - Extraire
deploy.internal/app/deployexiste, câblé depuiscmd/platform-factory/lifecycle.go. - Extraire
runtime. Pas de paquetinternal/app/runtimeunique ; les préoccupations runtime sont réparties entreinternal/app/microvmetinternal/app/observe(câblés depuislifecycle.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/pipelineexiste, câblé depuiscmd/platform-factory/evidence.goetpipeline.go.
La CLI finale doit seulement :
- parser ;
- charger ;
- appeler un service ;
- formater ;
- traduire l’erreur en code de sortie.
- Ajouter un test automatique d’architecture.
- Découpler
sdk/ocideinternal/oci. - Découpler
sdk/pipelinedeinternal/pipeline. - Découpler
internal/policydeinternal/plugin. - Découpler
internal/executordeinternal/cache. - Découpler
internal/executordeinternal/networking. - Découpler
internal/assembledeinternal/cache. - Supprimer
internal/assemble → internal/oci. Aucun importinternal/oci/ocirestant dansinternal/assemble; interdit explicitement parinternal/archtest'sdomainInfrastructureBoundaries. - Supprimer
internal/project → internal/oci. Idem : aucun import restant, interdit explicitement parinternal/archtest. - Classifier explicitement les dépendances
internal/* → api/v1*comme autorisées ou interdites. Non couvert pardomainInfrastructureBoundariesà ce jour. - Faire échouer CI sur toute nouvelle violation.
internal/archtest.CheckForbiddenImportsest appelé depuisinternal/archtest/archtest_test.go, donc exécuté par toutgo 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
- 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 ?"
- 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
OperationIDdanspublish. - Câbler
OperationIDdansdeploy. - Câbler
OperationIDdans 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.
- 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'sPluginBuildInputs/GeneratePluginProvenance, câblé depuiscmd/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 queManifest.Digest). - Définir une politique de confiance organisationnelle.
- Définir rotation et révocation opérationnelles.
- Interdire le réseau aux plugins
language. - Isolation Linux générique existante.
- Formaliser un
PermissionProfilepar famille.internal/plugin/permission_profile.go: une entrée parPluginFamily(Language/Analyzer/Build/Runtime/Deployment/Capability), seuils choisis à partir de mesures réelles documentées (pas devinés), câblé danssandbox_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 unServiceAccount/Role/RoleBindingminimal. - Pour KubeVirt : namespace borné. Le même code lie explicitement à
un
Role(jamais unClusterRole) 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 limitesPermissionProfileci-dessus, pas une assertion de configuration.
- Erreurs typées.
- Codes catégorisés.
-
Retryable(err). -
ExitCode(err). -
trace_iddans 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
- 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_idaux 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.
- Budget wall-clock pipeline.
- Budget OCI in-process.
- Mesure CPU/RSS réelle d’un processus enfant.
- Câbler
budget.FromProcessStatedansinternal/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.
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.
- 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
EvidenceBundlecanonique. - Associer tous les artefacts à leurs digests.
- Client Registry natif.
- Upload reprenable.
- Vérification des digests.
- Publication avec preuves.
- Ajouter
OperationIDau 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/sharedne puisse être supprimée accidentellement.
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.
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 ».
-
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 renommageinternal/oci→oci;go test -fuzzsur 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é.)*
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
- 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.
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.
- 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.
-
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.
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
--debugavec redaction. - Respecter
NO_COLOR. - Tester Bash.
- Tester Zsh.
- Tester Fish.
- Tester PowerShell.
- Tester chemins Unicode.
- Tester chemins avec espaces.
- Tester sans TTY.
- Hyperviseur.
- Sandbox.
- Docker.
- Podman.
- containerd.
- Kubernetes.
- Registry config.
- Vérifier un
RuntimeClassdemandé. - 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.
- 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 ».
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.
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é.
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.
Ne reprendre ces chantiers qu’après fermeture des principaux P0/P1.
- 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.
- 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.
- terminer
assemble/project → internal/oci; - câbler la machine à états dans un vrai parcours runtime ;
- câbler
OperationIDdanspublishpuisdeploy; - généraliser le journal durable des mutations ;
- terminer les profils de sandbox plugin ;
- terminer la provenance des plugins ;
- câbler
budget.FromProcessStatedans l’executor ; - terminer l’extraction CLI →
internal/app/*; - établir les trois E2E quotidiens ;
- ajouter les scénarios crash/recovery ;
- terminer les threat models ;
- commander les audits indépendants ;
- activer les protections de release ;
- seulement ensuite reprendre VMM/distributed.
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é
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.
© 2026 CYPT71
platform-factory
Core
- Architecture and OCI Layout
- Next-generation Architecture
- Architecture Decision Records
- Security Model
- Threat Model and Residual Risks
- Independent Security Review Process
- CLI Reference
- Project Configuration and Dependency Freezing
- mTLS Configuration
- Meine Graal
CI/CD
Running an image
- Production Adoption Guide
- Dockerfile Consumer
- Local Dev (Podman/macOS)
- MicroVM Support
- MicroVM Administration
- Large-image streaming
Operating