No description
Find a file
2026-07-29 18:07:31 +00:00
.mcp chore(lab): persist schema proof handoff 2026-07-28 00:56:07 +00:00
config feat(lab): add migration and rollback release gates 2026-07-27 03:26:45 +00:00
deploy fix(lab): pin host operations to a modern Node runtime 2026-07-29 17:50:26 +00:00
docs docs(lab): record canonical schema proof and Restic blocker 2026-07-28 00:55:27 +00:00
examples/runtime-pilot feat(lab): add Node runtime pilot and validate release rollback 2026-07-09 19:58:42 +00:00
public feat(lab): refactor admin cockpit for mobile 2026-07-27 05:50:19 +00:00
scripts fix(lab): accept optional candidate failure in strict restore proof 2026-07-29 18:07:31 +00:00
src fix(lab): read runtime status across container mounts 2026-07-28 00:48:38 +00:00
test fix(lab): accept optional candidate failure in strict restore proof 2026-07-29 18:07:31 +00:00
.dockerignore feat: harden static publication and backups 2026-07-09 23:12:35 +00:00
.env.example feat(lab): add read-only operational AI assistant 2026-07-27 04:51:12 +00:00
.gitignore feat: establish Kordin Lab Lot 1 foundation 2026-07-08 19:21:27 +00:00
AGENT_STATUS.md chore(lab): persist schema proof handoff 2026-07-28 00:56:07 +00:00
AGENTS.md docs(lab): formalize post-Lot 2F audit and hardening plan 2026-07-09 21:50:12 +00:00
package.json feat(lab): checkpoint authenticated backups and restore workflow 2026-07-26 15:48:57 +00:00
pnpm-lock.yaml feat: establish Kordin Lab Lot 1 foundation 2026-07-08 19:21:27 +00:00
pnpm-workspace.yaml feat: establish Kordin Lab Lot 1 foundation 2026-07-08 19:21:27 +00:00
README.md feat(lab): refactor admin cockpit for mobile 2026-07-27 05:50:19 +00:00
tsconfig.json feat: establish Kordin Lab Lot 1 foundation 2026-07-08 19:21:27 +00:00

Kordin Lab

Control plane personnel pour publier des expériences, déployer des runtimes et exploiter progressivement des services durables.

  • URL : https://lab.kordin.fr
  • code : /srv/apps/lab
  • données : /srv/lab
  • workspace MCP : lab

Fonctionnalités

  • portail privé HTTPS derrière Traefik et Basic Auth ;
  • publication atomique d'expériences statiques sous /<slug>/ ;
  • runtimes container bornés, sans port hôte ni volume utilisateur arbitraire ;
  • worker hôte restreint, sans socket Docker dans le serveur HTTP ;
  • liveness/readiness séparées, health checks, métriques structurées, snapshots de logs et journal runtime rotatif verrouillé ;
  • interface privée /admin avec actions sécurisées ;
  • déploiements container versionnés, référence dimage immuable et promotion après health check ;
  • snapshots Docker mutualisés, maintenance non chevauchante et concurrence bornée ;
  • nettoyage prudent des images avec dry-run et protection de lhistorique ;
  • rollback manuel, ciblé ou automatique ;
  • réconciliation de la configuration runtime désirée ;
  • pilote Node de référence validant API, préfixe, assets, logs et arrêt propre ;
  • rétention configurable des versions, aperçu de nettoyage, suppression bornée et diagnostics dorphelins ;
  • publication statique prévisualisable, bornée et sans suivi de symlinks ;
  • exclusions .labignore, contexte Docker filtré et rétention des backups statiques ;
  • contrôle-plane révisé avec CAS, verrous interprocessus et journal dopérations ;
  • file administrative FIFO avec quarantaine et déduplication ;
  • transitions static/container/remove explicites et récupérables ;
  • modèle canonique Project rétrocompatible avec profils experiment, service et worker ;
  • fiches opérationnelles Project avec états, preuves, releases et inconnues explicites ;
  • intégration de services externes en lecture seule, avec PixDrop comme premier service durable ;
  • observation Docker/HTTP/TLS/stockage/SQLite/Android sans mutation ;
  • contrats de données stricts avec criticité, propriétaire, dépendances et reconstructibilité ;
  • observations filesystem et SQLite expurgées, fraîches et purement en lecture seule ;
  • exigences déclaratives de sauvegarde, restauration et compatibilité de rollback ;
  • politiques de sauvegarde versionnées avec fréquence, rétention, destination logique et vérification ;
  • runner Restic hôte borné pour médias et SQLite cohérent, avec vérification, rétention et artefacts restaurables ;
  • attestations Ed25519 obligatoires pour qualifier une preuve comme protected ;
  • exercices de restauration isolés avec sandbox, budgets, contrôles filesystem/SQLite et nettoyage ;
  • scénario combiné PixDrop implémenté avec cohérence catalogue/médias, candidate isolée et rapport expurgé ; preuve réelle hôte encore requise avant clôture du Lot 5C ;
  • contrats de migration par release et gates avant Docker pour déploiement, rollback manuel, réconciliation et rollback automatique ;
  • snapshots immuables de compatibilité dans chaque version et refus prudent des versions historiques sans politique ;
  • cockpit affichant schéma observé, matrice de releases et raisons exactes des rollbacks bloqués ;
  • PixDrop volontairement blocked tant que ses vraies releases compatibles avec le schéma 5 ne sont pas déclarées ;
  • assistant opérationnel en lecture seule fondé uniquement sur les preuves Project expurgées ;
  • synthèse déterministe toujours disponible et Ollama optionnel avec JSON Schema, timeout, citations et fallback ;
  • faits et résumé conservés déterministes même lorsque le modèle enrichit les hypothèses et recommandations ;
  • aucun outil LLM, aucune mutation, aucun accès Docker, shell, SSH, secret, volume de production ou file administrative ;
  • cockpit mobile avec questions par projet, citations consultables et mode de réponse explicite ;
  • shell /admin mobile-first à vues exclusives : overview, projets, assistant et activité ;
  • listes compactes, recherche/filtres, actions repliées et fiches projet en accordéons plein écran sur téléphone ;
  • événements et diagnostics séparés au lieu dune page monolithique interminable ;
  • états protected, attention, unknown, ready, blocked, passed et failed sans faux succès ;
  • moteur de capacités Project strictement default-deny ;
  • politiques prospectives, par profil et surcharges complètes par projet ;
  • approbations courtes, exactes et consommables une seule fois ;
  • revalidation des mutations dans lAPI, le worker, la CLI et le wrapper hôte ;
  • commande diagnose produisant un bundle partageable sans secrets, logs bruts ni chemins internes ;
  • projection v3 sans mutation et migration v4 prévisualisable, sauvegardée et idempotente ;
  • configuration typée unique avec version et empreinte de politique ;
  • reverse proxy filtré, limites 400/413/504 et abandon upstream ;
  • service statique HEAD/Range/ETag/MIME/cache ;
  • en-têtes de sécurité et container Lab read-only sans capabilities.

Approbations des mutations

Inspecter la matrice effective :

node dist/src/cli.js project capabilities <slug>

Créer un jeton à usage unique :

node dist/src/cli.js project approve <slug> <action>

Puis transmettre son UUID uniquement au processus de mutation via LAB_PROJECT_APPROVAL_ID. Les wrappers hôte créent et injectent automatiquement ce jeton. Les dry-runs restent disponibles sans approbation lorsquils ne modifient rien.

PixDrop autorise view, diagnose, observe et status. Les seules mutations de données ouvertes dans le checkpoint sont backup et restore-exercise, toutes deux avec approbation à usage unique liée à la politique ou à lexercice exact. restore-production, restore et delete-data restent refusées.

Contrats de données

Lister les contrats expurgés et observer les preuves en lecture seule :

node dist/src/cli.js data list
node dist/src/cli.js data observe pix-drop

PixDrop déclare deux ressources critiques : la bibliothèque média et le catalogue SQLite. Leur présence, lisibilité, sentinel, intégrité et schéma sont observés sans exposer les chemins hôte.

Les exigences backup: required et restore: required ne signifient pas encore quune sauvegarde ou restauration a été prouvée. Les capacités backup, restore et delete-data restent deny jusquaux lots suivants.

Politiques de sauvegarde

Lister les politiques validées et évaluer les preuves externes disponibles :

node dist/src/cli.js backup list
node dist/src/cli.js backup evaluate pix-drop

PixDrop déclare une politique quotidienne pour les médias et une politique toutes les douze heures pour le catalogue. Les deux exigent une destination secondaire, une rétention multi-échelle et une vérification.

Le checkpoint contient désormais un runner hôte déterministe. Une preuve nest qualifiée protected que si le runner a exécuté la politique, vérifié la sauvegarde, appliqué la rétention et produit une attestation Ed25519 valide. La présence du code ne prouve pas encore que le repository secondaire de production est configuré ou quune sauvegarde réelle a réussi : tant que cette exécution nest pas faite, létat réel reste unknown ou blocked.

Commandes ajoutées :

node dist/src/cli.js backup run pix-drop media-daily manual
node dist/src/cli.js backup run pix-drop catalogue-daily manual
node dist/src/cli.js restore list
node dist/src/cli.js restore evaluate pix-drop
node dist/src/cli.js restore exercise pix-drop <exercise-id>

Les exécutions manuelles exigent une approbation ciblée. Les timers systemd utilisent une identité planifiée dédiée. Le scénario combiné est déclaré sous lidentifiant pixdrop-media-catalogue et se lance par la même commande restore exercise ; son exécution réelle doit encore réussir avant clôture du Lot 5C.

Gates de migration et rollback

Inspecter les contrats et simuler les décisions sans mutation :

node dist/src/cli.js migration list
node dist/src/cli.js migration inspect [slug]
node dist/src/cli.js migration gate-deploy <slug> <image>
node dist/src/cli.js migration gate-rollback <slug> [version]

Un projet sans ressource persistante sensible conserve le comportement historique. Pour un projet à données, Lab exige un contrat de release exact, une observation de schéma fraîche, une compatibilité de lecture/écriture, les prérequis de sauvegarde et la coexistence nécessaire avant le moindre appel Docker.

Chaque version autorisée mémorise une politique immuable. Une version historique sans cette politique ne devient jamais rétroactivement « compatible ». Les changements réels de schéma restent bloqués jusquà livraison dun exécuteur de migration dédié et de preuves avant/après.

Le contrat PixDrop est volontairement vide : aucune release réelle na été inventée. Le panel affiche donc blocked tant que la matrice schéma 5 nest pas renseignée à partir des vraies images et de leur compatibilité. Voir docs/LOT5D_MIGRATION_ROLLBACK_GATES.md.

Assistant opérationnel local

Le mode déterministe fonctionne sans modèle :

node dist/src/cli.js ai status
node dist/src/cli.js ai ask --project pix-drop --deterministic "Pourquoi PixDrop est-il bloqué ?"

Ollama peut être activé explicitement par configuration hôte. Il reçoit seulement un paquet borné de preuves déjà expurgées et doit retourner un JSON conforme à un schéma fermé, avec citations exactes. Les faits et le résumé publiés restent déterministes ; le modèle peut uniquement enrichir les hypothèses et recommandations citées.

Le cockpit /admin expose la même fonction. Aucune question ou réponse nest persistée, aucune commande nest générée, et la route ne crée ni action ni approbation. Lindisponibilité ou la réponse invalide du modèle provoque un fallback déterministe. Voir docs/LAB_AI_01_READONLY_ASSISTANT.md.

Manifeste statique

slug: ants-demo
title: Ants Demo
description: Simulation publiée dans le Lab
visibility: private
source: dist
pnpm run build
node dist/src/cli.js publish ./lab.yml --dry-run
LAB_PROJECT_APPROVAL_ID=<uuid-publish> node dist/src/cli.js publish ./lab.yml

La prévisualisation indique les fichiers inclus, les exclusions et les budgets appliqués. Sont exclus par défaut : lab.yml, .labignore, .git, .mcp, .mcp-tx, node_modules, .env, .env.*, coverage, .cache et *.log.

Un fichier .labignore placé à la racine de source peut ajouter des motifs simples avec *, ** et ?. Les négations ! sont refusées explicitement pour éviter une sémantique ambiguë. Les limites par défaut sont de 10 000 fichiers et 256 Mio ; elles peuvent être remplacées pour la CLI par LAB_STATIC_MAX_FILES et LAB_STATIC_MAX_BYTES.

visibility: unlisted masque lexpérience du portail et de lAPI de découverte tout en conservant laccès direct après Basic Auth. visibility: public est refusé tant que le domaine entier reste protégé par la Basic Auth globale.

Manifeste container

slug: node-demo
title: Node Demo
type: container
visibility: private
profile: experiment
runtime.image: node:24-alpine
runtime.port: 3000
runtime.healthcheck: /health
LAB_PROJECT_APPROVAL_ID=<uuid-publish> node dist/src/cli.js register ./lab.yml
LAB_PROJECT_APPROVAL_ID=<uuid-deploy> node dist/src/cli.js runtime deploy node-demo
node dist/src/cli.js runtime versions node-demo
LAB_PROJECT_APPROVAL_ID=<uuid-rollback> node dist/src/cli.js runtime rollback node-demo

Chaque version est démarrée hors trafic, validée par son health check, puis promue via l'alias réseau stable lab-active-<slug>. La version précédente reste disponible pour rollback. Le rollback automatique applique un seuil configurable, une période de grâce, un cooldown et une quarantaine anti-ping-pong.

Modèle Project

Les expériences existantes sont projetées en projets sans mutation du registre. La migration v4 est explicite :

node dist/src/cli.js project list
node dist/src/cli.js project migrate --dry-run
node dist/src/cli.js project migrate --apply
node dist/src/cli.js project profile node-demo service --dry-run
LAB_PROJECT_APPROVAL_ID=<uuid-change-profile> \
  node dist/src/cli.js project profile node-demo service

Les profils disponibles sont experiment, service et worker. Un worker nexpose aucune route HTTP, mais reste administrable. Un profil autre que experiment exige la migration v4 afin que lintention soit persistée sans ambiguïté.

Runtime Pilot Node

Le pilote réel est disponible sous :

https://lab.kordin.fr/runtime-pilot/

Il fournit :

  • /runtime-pilot/health ;
  • /runtime-pilot/api/info ;
  • une interface et des assets CSS/JS compatibles avec le préfixe ;
  • des logs JSON structurés ;
  • un arrêt gracieux sur SIGTERM et SIGINT.

La release désirée est stockée dans examples/runtime-pilot/release-version.txt. La v2 est la release finale active.

LAB_PROJECT_APPROVAL_ID=<uuid-prepare> \
  node dist/src/cli.js runtime prepare runtime-pilot
LAB_PROJECT_APPROVAL_ID=<uuid-start> \
  node dist/src/cli.js runtime start runtime-pilot
node dist/src/cli.js runtime status runtime-pilot

runtime status runtime-pilot vérifie l'image active, l'API directe, l'API via le reverse proxy Lab et les assets proxifiés.

Commandes principales

node dist/src/cli.js list
node dist/src/cli.js info <slug>
node dist/src/cli.js project list
node dist/src/cli.js project info <slug>
node dist/src/cli.js project capabilities <slug>
node dist/src/cli.js project approve <slug> <action>
node dist/src/cli.js project migrate --dry-run
node dist/src/cli.js project migrate --apply
node dist/src/cli.js project profile <slug> <experiment|service|worker> --dry-run
node dist/src/cli.js project profile <slug> <experiment|service|worker>
node dist/src/cli.js diagnose
node dist/src/cli.js diagnose <slug>
node dist/src/cli.js external list
node dist/src/cli.js external observe [slug]
node dist/src/cli.js data list
node dist/src/cli.js data observe [slug]
node dist/src/cli.js backup list
node dist/src/cli.js backup evaluate [slug]
node dist/src/cli.js backup run <slug> <policy-id> <manual|scheduled>
node dist/src/cli.js restore list
node dist/src/cli.js restore evaluate [slug]
node dist/src/cli.js restore exercise <slug> <exercise-or-scenario-id>
node dist/src/cli.js migration list
node dist/src/cli.js migration inspect [slug]
node dist/src/cli.js migration gate-deploy <slug> <image>
node dist/src/cli.js migration gate-rollback <slug> [version]
node dist/src/cli.js ai status
node dist/src/cli.js ai ask [--project <slug>] [--deterministic] <question>
node dist/src/cli.js runtime pilot-build runtime-pilot <version>
node dist/src/cli.js runtime deploy <slug>
node dist/src/cli.js runtime rollback <slug> [version]
node dist/src/cli.js runtime versions <slug>
node dist/src/cli.js runtime prune <slug> --dry-run
node dist/src/cli.js runtime prune <slug>
node dist/src/cli.js runtime prune-all --dry-run
node dist/src/cli.js runtime image-prune --dry-run
node dist/src/cli.js runtime image-prune --apply
node dist/src/cli.js static prune <slug> --dry-run
node dist/src/cli.js static prune <slug>
node dist/src/cli.js transition <slug> <static|container> <lab.yml> --dry-run
node dist/src/cli.js transition <slug> removed --dry-run
node dist/src/cli.js config
node dist/src/cli.js migrate
node dist/src/cli.js runtime start <slug>
node dist/src/cli.js runtime stop <slug>
node dist/src/cli.js runtime status <slug>
node dist/src/cli.js runtime logs <slug>
node dist/src/cli.js doctor

Le serveur HTTP reverse-proxy les runtimes versionnés par le réseau Docker, mais n'appelle jamais Docker directement.

Documentation :

  • docs/ARCHITECTURE.md
  • docs/OPERATIONS.md
  • docs/ROADMAP.md
  • docs/design/KORDIN_LAB_TARGET_ROADMAP_CONTROL_PLANE_AI.md
  • docs/LOT2G4_RESILIENCE_OBSERVABILITY_RECOVERY.md
  • docs/LOT2G5_SCALABILITY_MAINTAINABILITY.md
  • docs/LOT3A_PROJECT_MODEL.md
  • docs/LOT3B_PROJECT_OPERATIONS.md
  • docs/LOT3C_PIXDROP_READONLY.md
  • docs/LOT3D_PROJECT_CAPABILITIES.md
  • docs/LOT5A_DATA_CONTRACTS.md
  • docs/LOT5B_BACKUP_POLICIES.md
  • docs/LOT5C_RESTORE_EXERCISES.md
  • docs/LOT5D_MIGRATION_ROLLBACK_GATES.md
  • docs/LAB_AI_01_READONLY_ASSISTANT.md
  • docs/COCKPIT_MOBILE_UX.md
  • docs/HANDOFF_LAB_AI_01_WIP_2026-07-27.md
  • docs/HANDOFF_LOT5D_WIP_2026-07-27.md
  • docs/HANDOFF_LOT5C_COMBINED_WIP_2026-07-27.md
  • docs/HANDOFF_LOT5C_WIP_2026-07-26.md — historique
  • docs/PROMPT_REPRISE_LOT5C_5D_2026-07-26.md — prompt initial
  • docs/LOT2D_VERSIONED_DEPLOYMENTS.md
  • docs/LOT2E_NODE_RUNTIME_PILOT.md
  • docs/LOT2F_RUNTIME_LIFECYCLE.md
  • docs/audits/AUDIT_LAB_POST_LOT2F_2026-07-09.md
  • docs/design/PLAN_DIRECTEUR_CORRECTIF_POST_AUDIT_2026-07-09.md
  • docs/design/VALIDATION_MATRIX_POST_AUDIT_2026-07-09.md
  • docs/PROMPT_REPRISE_CORRECTIFS_POST_AUDIT_2026-07-09.md