kisenon
Agent-Safe Change Control

Sandboxes & promote

AI コーディングエージェントを本番データベースに安全に向ける — キャプチャされ、観察され、ゲートを通してプロモートされ、巻き戻し可能。

Agent-Safe Change Control の一部です。ここで説明する keon sandboxkeon ledger コマンド、およびコンソールの Sandboxes ビューは稼働中です — 最近の keon が必要です(cli-v0.1.46 以降)。

Kisenon では、コーディングエージェント(Claude Code、Cursor、あるいは独自のもの)に、 本番を危険にさらすことなく自由に変更できるデータベースを渡せます。サンドボックスとは、 スコープ限定の認証情報、ライブのアクションログ、そしてサーバー側の promote ステップを備えた、 ブランチの実行ごとのフォークです。このページはループ全体を扱います: キャプチャ → 作業 → プロモート → 着地(巻き戻し可能に)→ 証明

なぜ安全なのか

2 つの保証があり、いずれも決定論的です — 信頼の経路に LLM は存在しません。

  • エージェントは本番に触れられません。 エージェントは、スコープ限定・非スーパーユーザーの 認証情報でフォークに接続します。main に書き込める認証情報を保持することは決してありません。 プロモーションはサーバー側で実行され、サンドボックスですでに合格した変更のみを適用します。
  • 何をしたかを正確に確認できます。 すべてのステートメントは帰属付けされ、読み取り専用の コンソールにストリーミングされます — 要約ではなく、実際の SQL です。

ループ

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 main

エージェントはループの制御を保ち続けます。安全性をもたらすのは、その境界です。

永続的なキャプチャ

アクションログは promote の真実の源であるため、完全でなければなりません。各サンドボックスは capture_stateok または lost — を持ちます。キャプチャが損なわれると状態は lost に 反転し、そのままにとどまります: lost なサンドボックスは promote できず (409 sandbox_capture_lost)、部分的な変更をこっそり適用することは決してありません。 自動修復はありません — 破棄して、新しいサンドボックスで作業をやり直してください。 keon sandbox get / list がキャプチャの健全性を表示します。

プロモート: セルフサービス、または人間による承認

各プロジェクトは promote_mode を選択します。

モード誰が main にコミットするか
self(デフォルト)エージェントは、自身のチェックに合格すると — その境界の範囲内で — プロモートします。
humanエージェントは提案します。オーナー/管理者が差分とアクションログをレビューし、Approve をクリックします。

被害範囲のドライラン

プロモートする前に、ステートメントのテキストから推測するのではなく、promote が実際に何を するか — 実際のロックレベル、実際のロック保持時間、実際の行数 — をプラットフォームに 測定させることができます。

keon sandbox dry-run <id>

プラットフォームは、サンドボックスの正確なステートメント集合を、親の 2 つの短命な使い捨て フォーク — 1 つは親の現在の HEAD(ロック、継続時間、行数が測定される場所)、もう 1 つは サンドボックスのフォーク点(分岐のベースライン)— に対して再生し、その後両方を破棄します。 main には決して触れず、エージェントはどちらのフォークの認証情報も受け取りません。 ドライランは助言的です: レポートを生成しますが、promote をブロックすることは決して ありません。

これは静的な差分では答えられない問いにも答えます: エージェントの下で現実が動いたか? 親 HEAD でフォーク点と異なる数の行に影響する、あるいはエラーになるステートメントは、 コンフリクトとして表面化されます — 例えば、フォーク後に main で対象行が削除された UPDATE ... WHERE id = 2 です。

完了したレポートは次を含みます。

フィールド意味
statements[].lock_levelステートメントが promote トランザクションで新たに取得する最強のロック(例: テーブル書き換えの AccessExclusiveLock)。
statements[].lock_wait_est_mshead フォークでの測定実行時間 — main でロックが保持される時間の下限。
statements[].rows_measuredhead フォークで影響を受けた行数(DDL では 0)。
statements[].divergenceステートメントが HEAD でフォーク時と異なる振る舞いをするとき {kind:"error"} または {kind:"row_count"}
rollup.conflictsすべての分岐、およびベースラインレーンが実行できなかった場合の baseline_unavailable マーカー — そのため「コンフリクトなし」のゲートは劣化した測定に対してフェイルクローズドします。
rollup.max_lock_level / rollup.duration_ms_total集約されたロック強度と合計再生時間。
capture_advanced / parent_head_lsn陳腐化のシグナル: レポートはスナップショットであり、再実行は安価です。

エンドポイントは POST /v1/sandboxes/{id}/dry-run(非同期実行を開始、202)と GET /v1/sandboxes/{id}/dry-run(最新のレコード)です。失敗したドライランは機械可読な error_code を含みます (capture_fence_failedincomplete_capturefork_failedcompute_unreachablereplay_infra_failedtimeout)。サンドボックス詳細ページの Blast radius パネルは、コンソールで同じレポートを描画します。

プロモートを取り消す

promote は巻き戻し可能です。cp が検証済みステートメントを main に適用する前に、親ブランチの 正確なプロモート前状態(LSN)をアンカーします。1 つのコマンドがブランチをそのアンカーへ 巻き戻します。

keon sandbox undo <id>   # restore the parent branch to its pre-promote state

親の接続文字列は変わりません — クライアントは同じエンドポイントに再接続します。Undo は オーナー/管理者のアクションであり、エージェントケイパビリティのキーは拒否されます (403 scope_insufficient)。undo はアンカー以降にブランチに着地したものをすべて破棄する からです。

keon sandbox get <id>undo オブジェクトを持ちます — undoablerestored_lsnundone_at、および実行できないときの blocked_reasonsuperseded_by_later_promotealready_undone)。Undo は最も新しい promote のみを 対象とし、アンカーが失われると 409sandbox_not_promotedundo_anchor_missingundo_anchor_invalidated)で拒否します。アンカーが有効で、かつ ストレージ保持期間内である限り利用可能です — 別途のカウントダウンはありません。

Undo は LSN で復元します: プロモートされた変更だけでなく、アンカー以降のすべてを 巻き戻します — そのブランチへの直接書き込みや後続のエージェントセッションを含みます。 よくある落とし穴 を参照してください。

発行されるマイグレーション

着地したすべての promote は、決定論的な up/down SQL マイグレーションを発行します — LLM は 使わず、キャプチャされたスキーマ変更から生成され、提供される前に使い捨てフォーク上で ラウンドトリップ検証されます。取得するには:

keon sandbox migration <id> --out ./migrations --wait

このアーティファクトは up と down の SQL(files[]、それぞれに role を持つ)、coverage フラグ(full または partial)、down_fidelity、任意の uncovered_seqsvalidation 結果、および sha256 を含みます。終端状態は validatedvalidation_failedemission_failedno_schema_changes です。v1 は sql を発行します。 GET /v1/sandboxes/{id}/migration(および .../migration/files/{role})がこれを提供します。 発行は promote が着地した後に実行され、それをブロックしたり戻したりすることは決してありません — データのみの promote は単に no_schema_changes を報告します。

署名付き台帳

すべての promote と undo は、プロジェクトごとの台帳に署名付き・ハッシュチェーン化された レコードを追記します — 何が変わったかのオフライン検証可能なアテステーションです。検証には ネットワークが不要で、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 trust

keon ledger verify は Ed25519 署名とハッシュチェーンをチェックし、正確な失敗を報告します (signature_invalidstatement_chain_mismatchseq_gapkey_untrustedchain_broken、…)。信頼は 3 値 (trusted / untrusted / unverified)です。ルート: GET /v1/sandboxes/{id}/ledgerGET /v1/projects/{projectId}/ledgerGET /v1/ledger/keys

cp に署名鍵が設定されていない場合、promote は成功しますが署名されませんledger_enabled: false)— 署名は無条件ではありません。

サンドボックスではないもの

  • コードサンドボックスではありません — エージェントのプロセスではなく、あなたのデータベースを スコープします。
  • LLM ジャッジではありません — キャプチャ、再生、レビューはバイト単位で決定論的です。

試してみる

kisenon.com で試し、 クイックスタート をご覧ください。