Sandboxes & promote
AI 코딩 에이전트를 프로덕션 데이터베이스에 안전하게 겨누세요 — 캡처되고, 관찰되며, 게이트를 통해 프로모트되고, 되돌릴 수 있습니다.
Agent-Safe Change Control의 일부입니다. 여기에 설명된
keon sandbox및keon ledger명령과 콘솔 Sandboxes 뷰는 라이브입니다 — 최신 keon이 필요합니다(cli-v0.1.46+).
Kisenon을 사용하면 코딩 에이전트(Claude Code, Cursor, 직접 만든 것)에게 프로덕션을 위험에 빠뜨리지 않으면서 자유롭게 변경할 수 있는 데이터베이스를 넘길 수 있습니다. 샌드박스는 범위가 제한된 자격 증명, 실시간 작업 로그, 서버 측 프로모트 단계를 갖춘, 브랜치의 실행마다 생성되는 포크입니다. 이 페이지는 전체 루프를 다룹니다: 캡처 → 작업 → 프로모트 → 착지(되돌릴 수 있게) → 증명.
안전한 이유
두 가지 보장, 둘 다 결정론적입니다 — 신뢰 경로에 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에이전트는 루프를 계속 제어합니다. 그것을 안전하게 만드는 것은 경계입니다.
견고한 캡처
작업 로그는 프로모트의 진실 원천이므로 완전해야 합니다. 각 샌드박스는
capture_state — ok 또는 lost — 를 지닙니다. 캡처가 손상되면 상태가
lost로 뒤집히고 그대로 유지됩니다: lost 샌드박스는 프로모트할 수 없으며
(409 sandbox_capture_lost) 부분 변경을 조용히 적용하는 일은 결코 없습니다.
자동 복구는 없습니다 — 버리고 새 샌드박스에서 작업을 다시 실행하세요. keon sandbox get / list가 캡처 상태를 보여줍니다.
프로모트: 셀프서비스 또는 사람 승인
각 프로젝트는 promote_mode를 선택합니다:
| 모드 | main에 커밋하는 주체 |
|---|---|
self(기본값) | 에이전트가 검사를 통과하면 — 자기 경계 안에서 — 프로모트합니다. |
human | 에이전트가 제안하고, 소유자/관리자가 diff + 작업 로그를 검토한 뒤 Approve를 클릭합니다. |
폭발 반경 드라이런
프로모트하기 전에, 문장 텍스트로 추측하는 대신 프로모트가 무엇을 할지를 플랫폼에 측정하도록 요청할 수 있습니다 — 실제 락 수준, 실제 락 보유 시간, 실제 행 수:
keon sandbox dry-run <id>플랫폼은 샌드박스의 정확한 문장 집합을 부모의 수명이 짧은 일회성 포크 두 개에
대해 재생합니다 — 하나는 부모의 현재 HEAD(락, 지속 시간, 행이 측정되는 곳)이고
다른 하나는 샌드박스의 포크 지점(발산 기준선) — 그런 다음 둘 다 파괴합니다.
main에는 결코 손대지 않으며, 에이전트는 어느 포크에도 자격 증명을 받지
않습니다. 드라이런은 권고입니다: 리포트를 생성할 뿐, 프로모트를 결코
차단하지 않습니다.
또한 정적 diff가 답할 수 없는 질문에 답합니다: 에이전트 아래에서 현실이
움직였는가? 포크 지점에서와 다르게 부모 HEAD에서 오류를 내거나 다른 수의 행에
영향을 미치는 문장은 **충돌(conflict)**로 표면화됩니다 — 예: 대상 행이 포크
이후 main에서 삭제된 UPDATE ... WHERE id = 2.
완료된 리포트는 다음을 담습니다:
| 필드 | 의미 |
|---|---|
statements[].lock_level | 프로모트 트랜잭션에서 문장이 새로 취하는 가장 강한 락(예: 테이블 재작성의 경우 AccessExclusiveLock). |
statements[].lock_wait_est_ms | 헤드 포크에서 측정된 실행 시간 — main에서 락이 유지되는 시간의 하한. |
statements[].rows_measured | 헤드 포크에서 영향받은 행(DDL의 경우 0). |
statements[].divergence | 문장이 포크 시점과 HEAD에서 다르게 동작할 때 {kind:"error"} 또는 {kind:"row_count"}. |
rollup.conflicts | 모든 발산, 그리고 기준선 레인이 실행되지 못한 경우 baseline_unavailable 마커 — 그래서 "충돌 없음"에 대한 게이트는 저하된 측정에서 **닫힘(closed)**으로 실패합니다. |
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_failed, incomplete_capture, fork_failed,
compute_unreachable, replay_infra_failed, timeout). 샌드박스 상세
페이지의 Blast radius 패널이 콘솔에서 동일한 리포트를 렌더링합니다.
프로모트 되돌리기
프로모트는 되돌릴 수 있습니다. cp가 검증된 문장을 main에 적용하기 전에, 부모
브랜치의 정확한 프로모트 이전 상태(LSN)를 앵커합니다. 한 명령이 브랜치를 그
앵커로 롤백합니다:
keon sandbox undo <id> # restore the parent branch to its pre-promote state부모의 연결 문자열은 변경되지 않습니다 — 클라이언트는 같은 엔드포인트로 다시
연결합니다. Undo는 소유자/관리자 작업이며, 에이전트 기능 키는 거부됩니다
(403 scope_insufficient). undo가 앵커 이후 브랜치에 착지한 모든 것을 버리기
때문입니다.
keon sandbox get <id>는 undo 객체 — undoable, restored_lsn,
undone_at, 그리고 실행할 수 없을 때의 blocked_reason
(superseded_by_later_promote, already_undone) — 를 담습니다. Undo는 가장
최근 프로모트만 대상으로 하며, 앵커가 사라지면 409
(sandbox_not_promoted, undo_anchor_missing, undo_anchor_invalidated)로
거부합니다. 앵커가 유효하고 스토리지 보존 기간 안에 있는 동안 사용 가능하게
유지됩니다 — 별도의 카운트다운은 없습니다.
Undo는 LSN으로 복원합니다: 프로모트된 변경만이 아니라 앵커 이후의 모든 것을 롤백합니다 — 그 브랜치의 직접 쓰기와 이후 에이전트 세션을 포함해서요. Common pitfalls를 참조하세요.
방출된 마이그레이션
착지한 모든 프로모트는 결정론적 up/down SQL 마이그레이션을 방출합니다 — LLM 없이, 캡처된 스키마 변경으로부터 생성되어 제공되기 전에 일회성 포크에서 왕복 검증됩니다. 가져오기:
keon sandbox migration <id> --out ./migrations --wait아티팩트는 up 및 down SQL(files[], 각각 role을 가짐), coverage 플래그
(full 또는 partial), down_fidelity, 모든 uncovered_seqs, validation
결과, 그리고 sha256을 담습니다. 종단 상태는 validated, validation_failed,
emission_failed, no_schema_changes입니다. v1은 sql을 방출합니다. GET /v1/sandboxes/{id}/migration(및 .../migration/files/{role})이 그것을
제공합니다. 방출은 프로모트가 착지한 뒤에 실행되며 결코 그것을 차단하거나
되돌리지 않습니다 — 데이터 전용 프로모트는 그저 no_schema_changes를
보고합니다.
서명된 원장
모든 프로모트와 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 trustkeon ledger verify는 Ed25519 서명과 해시 체인을 검사하고 정확한 실패를
보고합니다(signature_invalid, statement_chain_mismatch, seq_gap,
key_untrusted, chain_broken, …). 신뢰는 세 가지 상태입니다(trusted /
untrusted / unverified). 경로: GET /v1/sandboxes/{id}/ledger, GET /v1/projects/{projectId}/ledger, GET /v1/ledger/keys.
cp에 서명 키가 구성되어 있지 않으면 프로모트는 여전히 성공하지만 서명되지 않습니다(
ledger_enabled: false) — 서명은 무조건적이지 않습니다.
샌드박스가 아닌 것
- 코드 샌드박스가 아닙니다 — 에이전트의 프로세스가 아니라 당신의 데이터베이스에 범위를 제한합니다.
- LLM 심판이 아닙니다 — 캡처, 재생, 검토는 바이트 단위로 결정론적입니다.
사용해 보기
kisenon.com에서 사용해 보고 빠른 시작을 확인하세요.