Sandboxes & promote
Pointez un agent de code IA vers votre base de données de production en toute sécurité — capturé, observé, promu par une porte, et réversible.
Fait partie de Agent-Safe Change Control. Les commandes
keon sandboxetkeon ledgerainsi que la vue Sandboxes de la console décrites ici sont en service — un keon récent est requis (cli-v0.1.46+).
Kisenon vous permet de confier à un agent de code (Claude Code, Cursor, le vôtre) une base de données qu'il peut modifier librement — sans risquer la production. Un sandbox est un fork par exécution de votre branche, avec une identification à portée limitée, un journal d'actions en direct, et une étape de promotion côté serveur. Cette page couvre la boucle complète : capture → travail → promote → atterrissage (réversible) → preuve.
Pourquoi c'est sûr
Deux garanties, toutes deux déterministes — aucun LLM ne siège dans le chemin de confiance :
- L'agent ne peut pas toucher la production. Il se connecte avec une identification à portée limitée,
non-superutilisateur, vers un fork. Il ne détient jamais d'identification capable
d'écrire sur
main. La promotion s'exécute côté serveur et n'applique que des changements qui ont déjà réussi dans le sandbox. - Vous voyez exactement ce qu'il a fait. Chaque instruction est attribuée et diffusée vers une console en lecture seule — le vrai SQL, pas un résumé.
La boucle
keon sandbox run \
--migrate "alembic upgrade head" \
--verify "pytest tests/db"
# → green/red verdict + schema diff + a sandbox you can inspect
keon sandbox promote <id> # cp applies the validated changes to mainL'agent garde le contrôle de la boucle ; c'est la borne qui la rend sûre.
Capture durable
Le journal d'actions est la source de vérité pour la promotion, il doit donc être complet.
Chaque sandbox porte un capture_state — ok ou lost. Si la capture est un jour
compromise, l'état bascule vers lost et y reste : un sandbox perdu
ne peut pas promouvoir (409 sandbox_capture_lost) et n'applique jamais silencieusement un
changement partiel. Il n'y a pas d'auto-réparation — jetez-le et rejouez le travail dans un
sandbox neuf. keon sandbox get / list montrent la santé de la capture.
Promote : en libre-service ou approuvé par un humain
Chaque projet choisit un promote_mode :
| Mode | Qui valide sur main |
|---|---|
self (défaut) | L'agent promeut une fois ses vérifications passées — dans ses bornes. |
human | L'agent propose ; un owner/admin examine le diff + le journal d'actions et clique sur Approve. |
Essai à blanc du rayon d'explosion
Avant de promouvoir, vous pouvez demander à la plateforme de mesurer ce que la promotion ferait — niveaux de verrou réels, durées de maintien de verrou réelles, nombres de lignes réels — au lieu de deviner à partir du texte des instructions :
keon sandbox dry-run <id>La plateforme rejoue le jeu d'instructions exact du sandbox contre deux forks jetables
éphémères du parent — l'un au HEAD courant du parent (où les verrous,
durées et lignes sont mesurés) et l'un au point de fork du sandbox (la
ligne de base de divergence) — puis détruit les deux. Elle ne touche jamais main, et
l'agent ne reçoit jamais d'identification vers l'un ou l'autre fork. L'essai à blanc est consultatif :
il produit le rapport, il ne bloque jamais une promotion.
Il répond aussi à la question qu'un diff statique ne peut pas : la réalité a-t-elle bougé sous
l'agent ? Toute instruction qui échoue, ou qui affecte un nombre de lignes différent, au
HEAD du parent par rapport à ce qu'elle faisait au point de fork est signalée comme un conflit — p. ex.
un UPDATE ... WHERE id = 2 dont la ligne cible a été supprimée sur main après le
fork.
Le rapport achevé porte :
| Champ | Signification |
|---|---|
statements[].lock_level | Le verrou le plus fort que l'instruction prend nouvellement dans la transaction de promotion (p. ex. AccessExclusiveLock pour une réécriture de table). |
statements[].lock_wait_est_ms | Temps d'exécution mesuré sur le fork de tête — le plancher de la durée de maintien du verrou sur main. |
statements[].rows_measured | Lignes affectées sur le fork de tête (0 pour du DDL). |
statements[].divergence | {kind:"error"} ou {kind:"row_count"} quand l'instruction se comporte différemment au HEAD qu'au moment du fork. |
rollup.conflicts | Chaque divergence, plus un marqueur baseline_unavailable si le couloir de ligne de base n'a pas pu s'exécuter — de sorte qu'une porte sur « aucun conflit » échoue fermée sur une mesure dégradée. |
rollup.max_lock_level / rollup.duration_ms_total | Force de verrou agrégée et temps de rejeu total. |
capture_advanced / parent_head_lsn | Signaux de péremption : le rapport est un instantané, et le relancer est peu coûteux. |
Les points de terminaison sont POST /v1/sandboxes/{id}/dry-run (démarre une exécution asynchrone, 202)
et GET /v1/sandboxes/{id}/dry-run (le dernier enregistrement). Un essai à blanc échoué
porte un error_code lisible par machine
(capture_fence_failed, incomplete_capture, fork_failed,
compute_unreachable, replay_infra_failed, timeout). Le panneau Blast radius
sur la page de détail du sandbox affiche le même rapport dans la console.
Annuler une promotion
Une promotion est réversible. Avant que cp n'applique les instructions validées à
main, il ancre l'état exact d'avant-promotion de la branche parente (un LSN). Une
commande ramène la branche à cet ancrage :
keon sandbox undo <id> # restore the parent branch to its pre-promote stateLa chaîne de connexion du parent est inchangée — les clients se reconnectent au même
point de terminaison. Undo est une action owner/admin ; les clés à capacité d'agent sont refusées
(403 scope_insufficient), car une annulation écarte tout ce qui a atterri sur la
branche après l'ancrage.
keon sandbox get <id> porte un objet undo — undoable, restored_lsn,
undone_at, et un blocked_reason quand il ne peut pas s'exécuter
(superseded_by_later_promote, already_undone). Undo cible la promotion la plus
récente uniquement, et rejette avec 409 (sandbox_not_promoted,
undo_anchor_missing, undo_anchor_invalidated) une fois l'ancrage disparu.
Il reste disponible tant que l'ancrage est valide et dans votre rétention de
stockage — il n'y a pas de compte à rebours distinct.
Undo restaure par LSN : il annule tout ce qui suit l'ancrage, pas seulement le changement promu — y compris les écritures directes et les sessions d'agent ultérieures sur cette branche. Voir Common pitfalls.
Migrations émises
Chaque promotion atterrie émet une migration SQL up/down déterministe — aucun LLM, générée à partir du changement de schéma capturé et validée par aller-retour sur un fork jetable avant d'être proposée. Récupérez-la :
keon sandbox migration <id> --out ./migrations --waitL'artefact porte le SQL up et down (files[], chacun avec un role), un
drapeau coverage (full ou partial), down_fidelity, tout uncovered_seqs,
un résultat validation, et un sha256. Les états terminaux sont validated,
validation_failed, emission_failed, et no_schema_changes. v1 émet
sql ; GET /v1/sandboxes/{id}/migration (et .../migration/files/{role})
le servent. L'émission s'exécute après l'atterrissage de la promotion et ne la bloque ni ne la
retourne jamais — une promotion de données uniquement rapporte simplement no_schema_changes.
Registre signé
Chaque promotion et annulation ajoute un enregistrement signé et chaîné par hachage à un registre par projet — une attestation vérifiable hors ligne de ce qui a changé. La vérification ne nécessite aucun réseau et ne fait pas confiance à Kisenon :
keon ledger list --project <id> # the chain (reports chain_ok)
keon ledger export <id> --out att.json # one attestation document
keon ledger verify att.json # offline; exit 0 iff valid
keon ledger keys --save # pin the signing keys you trustkeon ledger verify vérifie les signatures Ed25519 et la chaîne de hachage et
rapporte les échecs précis (signature_invalid, statement_chain_mismatch,
seq_gap, key_untrusted, chain_broken, …) ; la confiance est tri-état
(trusted / untrusted / unverified). Routes : GET /v1/sandboxes/{id}/ledger, GET /v1/projects/{projectId}/ledger, GET /v1/ledger/keys.
Si cp n'a aucune clé de signature configurée, les promotions réussissent quand même mais sont non signées (
ledger_enabled: false) — la signature n'est pas inconditionnelle.
Ce qu'un sandbox n'est pas
- Pas un sandbox de code — il limite la portée de votre base de données, pas le processus de l'agent.
- Pas un juge LLM — capture, rejeu et revue sont déterministes au niveau de l'octet.
Essayez-le
Essayez-le sur kisenon.com et voyez le quickstart.
Agent-Safe Change Control (ASCC)
Le système qui vous permet de pointer un agent IA vers une véritable base de données en toute sécurité — borné, attribué, révisé, réversible.
Guardrails
Budgets, paliers de politique, autorité à portée limitée, lint de risque et vérifications du rayon d'explosion — ce qui arrête un agent avant qu'il ne vous nuise.