<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Execution Receipt on jyukki's Blog</title><link>https://jyukki.com/tags/execution-receipt/</link><description>Recent content in Execution Receipt on jyukki's Blog</description><generator>Hugo -- 0.147.0</generator><language>ko-kr</language><lastBuildDate>Tue, 14 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://jyukki.com/tags/execution-receipt/index.xml" rel="self" type="application/rss+xml"/><item><title>2026 개발 트렌드: Execution Receipt, 에이전트 자동화는 로그가 아니라 검증 가능한 작업 영수증으로 넘어간다</title><link>https://jyukki.com/posts/2026-04-14-execution-receipt-agent-operations-trend/</link><pubDate>Tue, 14 Apr 2026 00:00:00 +0000</pubDate><guid>https://jyukki.com/posts/2026-04-14-execution-receipt-agent-operations-trend/</guid><description>에이전트가 실제 쓰기 작업과 운영 액션을 수행하기 시작하면서, 단순 로그만으로는 승인, 권한, 실행, 결과를 설명하기 어려워졌습니다. 최근 팀들이 execution receipt 계층을 두는 이유와 실무 기준을 정리합니다.</description><content:encoded><![CDATA[<p>AI 에이전트가 초반에는 읽기 중심으로만 움직일 때는 로그와 트레이스로도 어느 정도 운영이 됩니다. 하지만 문서 수정, 코드 변경, 외부 전송, 배포 트리거처럼 실제 효과가 있는 작업이 늘어나면 곧 질문이 바뀝니다. <strong>누가 실행했는가</strong>보다 <strong>왜 이 액션이 허용됐고, 어떤 승인과 어떤 권한으로, 어떤 입력을 기준으로 실행됐는가</strong>를 설명해야 하기 때문입니다.</p>
<p>문제는 기존 로그 체계가 이 질문에 잘 답하지 못한다는 점입니다. 승인 이벤트는 메시징 시스템에 있고, 세션 컨텍스트는 다른 저장소에 있고, 실제 툴 호출은 런타임 로그에 있고, 변경 결과는 Git 또는 파일 시스템에 있고, 나중에 붙인 증거는 또 다른 대시보드에 흩어집니다. 운영자가 사고 후 30분 안에 알고 싶은 것은 &ldquo;어느 서비스에서 오류가 났나&quot;만이 아닙니다. <strong>이 액션이 원래 의도와 같은 작업이었나, 범위를 넘었나, 같은 실행이 재시도 중복으로 두 번 발생했나</strong>가 더 중요해집니다.</p>
<p>그래서 최근 성숙한 팀들이 도입하는 것이 execution receipt입니다. 저는 이 흐름이 <a href="/posts/2026-04-05-tool-permission-manifest-runtime-attestation-trend/">Tool Permission Manifest + Runtime Attestation</a>에서 말한 &ldquo;원칙적 허용 범위&rdquo;, <a href="/posts/2026-04-12-action-lineage-agent-observability-graph-trend/">Action Lineage Graph</a>에서 말한 &ldquo;실행 계보&rdquo;, <a href="/posts/2026-04-13-capability-lease-expiring-agent-permissions-trend/">Capability Lease</a>에서 말한 &ldquo;작업 단위 임시 권한&rdquo; 사이의 빈칸을 메우는 계층이라고 봅니다. manifest가 가능 범위를 정하고, lineage가 연결 관계를 보여주고, lease가 현재 작업의 권한을 제한한다면, receipt는 <strong>이번 액션이 실제로 어떻게 수행됐는지 설명 가능한 단위</strong>를 만듭니다. 실무적으로는 <a href="/learning/deep-dive/deep-dive-execution-receipt-operations-playbook/">Execution Receipt 운영 플레이북</a>처럼 receipt를 어떤 액션부터 붙이고, 어떤 필드부터 강제하고, 어떤 경보를 먼저 올릴지까지 같이 설계해야 효과가 납니다.</p>
<h2 id="이-글에서-얻는-것">이 글에서 얻는 것</h2>
<ul>
<li>단순 로그와 trace만으로는 왜 에이전트 운영 설명 가능성이 부족한지 구체적으로 이해할 수 있습니다.</li>
<li>execution receipt에 어떤 필드가 반드시 들어가야 실무에서 감사, 재시도 방지, 승인 검증에 쓸 수 있는지 기준을 잡을 수 있습니다.</li>
<li>외부 전송, 코드 수정, 운영 액션을 어떤 순서로 receipt화해야 투자 대비 효과가 큰지 우선순위를 세울 수 있습니다.</li>
</ul>
<h2 id="핵심-개념이슈">핵심 개념/이슈</h2>
<h3 id="1-execution-receipt는-로그를-대체하는-것이-아니라-행동-단위-설명-레코드를-추가하는-것이다">1) execution receipt는 로그를 대체하는 것이 아니라 &ldquo;행동 단위 설명 레코드&quot;를 추가하는 것이다</h3>
<p>로그와 trace는 여전히 필요합니다. 문제는 둘 다 이벤트 흐름은 잘 보여주지만, <strong>행동의 의미와 정당성</strong>을 한 번에 설명하지는 못한다는 점입니다.</p>
<p>예를 들어 에이전트가 저장소 파일 12개를 수정했다고 합시다. 기존 로그에는 다음 정보가 흩어져 있을 가능성이 큽니다.</p>
<ul>
<li>사용자가 어떤 요청을 했는지</li>
<li>어느 세션에서 작업했는지</li>
<li>어떤 도구를 호출했는지</li>
<li>어떤 파일이 바뀌었는지</li>
<li>테스트가 통과했는지</li>
</ul>
<p>하지만 운영자가 실제로 필요한 질문은 더 날카롭습니다.</p>
<ul>
<li>이 수정은 승인된 범위 안이었나</li>
<li>원래 intent는 문서 수정이었는데 코드 수정까지 번진 것 아닌가</li>
<li>같은 액션이 timeout 뒤 재시도로 한 번 더 실행된 것 아닌가</li>
<li>handoff 뒤 다른 세션이 이어받으면서 권한과 문맥이 바뀌지 않았나</li>
</ul>
<p>execution receipt는 이런 질문에 답하기 위해, 액션 1개 또는 논리적 작업 1개를 기준으로 intent, approval, lease, tool input, evidence, effect를 묶은 레코드입니다. 즉 &ldquo;무슨 로그가 있었나&quot;가 아니라 **&ldquo;이 행동은 어떤 계약 아래 실행됐고 실제로 무엇을 남겼나&rdquo;**를 보여주는 단위입니다.</p>
<h3 id="2-최소-receipt-스키마는-생각보다-작아도-되지만-승인과-결과를-반드시-동시에-묶어야-한다">2) 최소 receipt 스키마는 생각보다 작아도 되지만, 승인과 결과를 반드시 동시에 묶어야 한다</h3>
<p>처음부터 거대한 감사 시스템이 필요한 것은 아닙니다. 다만 아래 필드는 있어야 receipt가 실제로 쓸모가 있습니다.</p>
<ul>
<li><code>receipt_id</code></li>
<li><code>intent_id</code> 또는 <code>task_id</code></li>
<li><code>subject_id</code>(에이전트/세션/하위 실행자)</li>
<li><code>approval_ref</code></li>
<li><code>capability_lease_ref</code></li>
<li><code>tool_action</code>과 주요 입력 digest</li>
<li><code>resource_scope</code>(저장소, 경로, 서비스, 환경)</li>
<li><code>expected_effect</code></li>
<li><code>actual_effect</code></li>
<li><code>evidence_refs</code>(diff, test result, message id, artifact hash)</li>
<li><code>started_at</code>, <code>completed_at</code></li>
<li><code>outcome</code>(success, partial, denied, expired)</li>
<li><code>replay_guard_key</code> 또는 duplicate suppression key</li>
</ul>
<p>여기서 특히 중요한 것은 <code>expected_effect</code>와 <code>actual_effect</code>를 분리하는 것입니다. 승인 당시 의도는 &ldquo;문서 2개 수정&quot;이었는데 결과가 &ldquo;문서 2개 + 설정 파일 1개 변경&quot;이라면, receipt가 있어야 범위 초과를 기계적으로 잡을 수 있습니다. 이 구조는 <a href="/posts/2026-04-10-test-evidence-pipeline-ai-change-review-trend/">Test Evidence Pipeline</a>에서 말한 증거 수집과 자연스럽게 이어집니다.</p>
<h3 id="3-왜-지금-중요해졌나-긴-세션-멀티에이전트-승인-지연이-겹치기-때문이다">3) 왜 지금 중요해졌나: 긴 세션, 멀티에이전트, 승인 지연이 겹치기 때문이다</h3>
<p>단발성 챗봇에서는 receipt가 과할 수 있습니다. 하지만 최근 운영 패턴은 다릅니다.</p>
<ul>
<li>세션이 스레드 또는 프로젝트 단위로 오래 유지됩니다.</li>
<li>보조 에이전트가 조사, 수정, 검증을 분담합니다.</li>
<li>사람 승인 후 실제 실행까지 몇 분에서 몇 시간의 간격이 생깁니다.</li>
<li>실행 환경이 sandbox snapshot이나 checkpoint로 이어집니다.</li>
</ul>
<p>이 구조에서는 &ldquo;누가 버튼을 눌렀나&quot;보다 <strong>같은 문맥이 계속 유지되고 있었나</strong>가 더 중요합니다. 그래서 <a href="/posts/2026-04-09-harness-engineering-agent-runtime-frame-trend/">Harness Engineering</a>, <a href="/posts/2026-04-11-stateful-sandbox-snapshot-environment-replay-trend/">Stateful Sandbox Snapshot</a>, <a href="/posts/2026-04-13-capability-lease-expiring-agent-permissions-trend/">Capability Lease</a> 같은 흐름이 함께 나옵니다. execution receipt는 그 사이에서 &ldquo;이 시점의 실행&quot;을 잘라 기록하는 역할을 합니다.</p>
<p>즉, receipt가 없으면 lineage는 있어도 각 edge의 의미가 흐리고, lease는 있어도 실제 사용 결과가 설명되지 않고, approval은 있어도 실행 결과와 자동으로 연결되지 않습니다.</p>
<h3 id="4-receipt의-가치는-감사보다-운영-안정성에서-먼저-드러난다">4) receipt의 가치는 감사보다 운영 안정성에서 먼저 드러난다</h3>
<p>많은 팀이 receipt를 compliance나 사후 포렌식용으로만 생각합니다. 그런데 실제로 더 큰 가치는 운영 품질에서 나옵니다.</p>
<p>첫째, <strong>중복 실행 방지</strong>가 쉬워집니다. 동일한 <code>intent_id + resource_scope + replay_guard_key</code> 조합이 있으면 timeout 뒤 재시도 시 같은 효과를 한 번 더 내지 않게 막을 수 있습니다.</p>
<p>둘째, <strong>handoff 품질이 올라갑니다.</strong> 다른 세션이나 다른 에이전트가 이어받을 때 &ldquo;이전까지 무엇이 이미 실행됐고 무엇이 아직 계획 단계인지&quot;를 receipt로 구분할 수 있습니다.</p>
<p>셋째, <strong>범위 초과 감지</strong>가 빨라집니다. 원래 허용 범위보다 많은 파일, 더 넓은 경로, 다른 환경에 영향을 주면 receipt 발급 단계에서 바로 경고를 만들 수 있습니다.</p>
<p>넷째, <strong>사람 검토 UX가 좋아집니다.</strong> 리뷰어는 장문의 로그 대신 intent, diff 요약, evidence 링크, lease 범위, 결과를 한 화면에서 볼 수 있습니다.</p>
<p>즉 receipt는 뒤늦게 보는 감사 레코드가 아니라, <strong>실행 중 판단 품질을 높이는 운영 단위</strong>입니다.</p>
<h3 id="5-핵심-kpi도-자동화율보다-설명-가능-비율을-봐야-한다">5) 핵심 KPI도 자동화율보다 &ldquo;설명 가능 비율&quot;을 봐야 한다</h3>
<p>성숙한 팀은 단순 자동화율보다 아래 숫자를 먼저 보기 시작합니다.</p>
<ul>
<li><code>receipt_coverage</code>: 효과가 있는 액션 중 receipt가 생성된 비율</li>
<li><code>unverifiable_action_rate</code>: 결과는 남았는데 approval 또는 evidence 연결이 안 되는 액션 비율</li>
<li><code>approval_to_receipt_p95</code>: 승인 이후 실제 receipt 완료까지 걸리는 시간</li>
<li><code>evidence_completeness_ratio</code>: diff, test, artifact hash, message id 등 필수 evidence가 모두 채워진 비율</li>
<li><code>duplicate_execution_rate</code>: 동일 intent가 중복 실행된 비율</li>
</ul>
<p>특히 외부 전송, 운영 변경, 데이터 쓰기 같은 고위험 액션은 coverage가 100%에 가까워야 합니다. 여기서 빠진 액션은 단순 누락이 아니라 <strong>설명 불가능한 실행</strong>입니다.</p>
<h2 id="실무-적용">실무 적용</h2>
<h3 id="1-어디부터-receipt화할까-위험도와-복구-난이도로-순서를-정하는-편이-맞다">1) 어디부터 receipt화할까: 위험도와 복구 난이도로 순서를 정하는 편이 맞다</h3>
<p>추천 우선순위는 아래입니다.</p>
<ol>
<li><strong>외부 전송, 운영 액션, 권한 변경</strong><br>
복구가 어렵고 설명 책임이 큽니다. 가장 먼저 100% receipt를 붙여야 합니다.</li>
<li><strong>코드/문서 쓰기 액션</strong><br>
diff와 테스트 evidence가 연결되기 쉬워 효과가 빠르게 보입니다.</li>
<li><strong>DB 쓰기, 배치 트리거, 환경 설정 변경</strong><br>
의도와 결과 차이를 잡는 데 receipt가 강하게 작동합니다.</li>
<li><strong>읽기 전용 조사 액션</strong><br>
나중에 coverage를 넓힐 때 포함하되, 초기에는 과투자할 필요가 없습니다.</li>
</ol>
<p>초기 설계 우선순위는 보통 <strong>범위 초과 차단 &gt; 중복 실행 방지 &gt; 리뷰 설명 가능성 &gt; 분석 편의성</strong> 순이 안전합니다.</p>
<h3 id="2-권장-운영-기준숫자조건우선순위">2) 권장 운영 기준(숫자·조건·우선순위)</h3>
<p>시작값으로는 아래 정도가 현실적입니다.</p>
<ul>
<li>외부 전송, 운영 변경, 권한 변경 액션: <strong>receipt coverage 100%</strong></li>
<li>로컬 파일 수정, 코드 변경 액션: <strong>95% 이상</strong></li>
<li><code>unverifiable_action_rate</code>: <strong>0.1% 미만</strong></li>
<li><code>approval_to_receipt_p95</code>: <strong>60초 미만</strong></li>
<li><code>evidence_completeness_ratio</code>: <strong>95% 이상</strong></li>
<li><code>duplicate_execution_rate</code>: <strong>0.5% 미만</strong></li>
<li>receipt 생성 오버헤드: 동기 경로 기준 <strong>p95 150ms 이하</strong>, 그 이상이면 비동기 finalize 검토</li>
</ul>
<p>추가 조건으로는 아래 정도가 유용합니다.</p>
<ul>
<li>파일 수정이 <strong>10개 초과</strong>이거나 환경 영향 범위가 <strong>1개 이상 서비스</strong>로 넓어지면 hierarchical receipt 또는 재승인 요구</li>
<li>approval 후 <strong>10분 이상</strong> 실행이 지연되면 기존 receipt draft 폐기 후 context 재검증</li>
<li>lease가 만료되었는데 actual effect가 발생하면 무조건 실패 receipt와 경보 생성</li>
</ul>
<p>이 숫자는 절대값이 아니라 출발점입니다. 중요한 것은 속도보다 <strong>설명 불가능한 액션을 먼저 없애는 것</strong>입니다.</p>
<h3 id="3-receipt-발급-파이프라인-예시">3) receipt 발급 파이프라인 예시</h3>
<p>실무에서는 아래 흐름이 가장 단순합니다.</p>
<ol>
<li>사용자의 요청이나 자동 정책이 <code>intent</code>를 만든다.</li>
<li>approval과 capability lease가 있으면 intent에 연결한다.</li>
<li>실제 tool action 직전 <code>receipt draft</code>를 발급한다.</li>
<li>실행 중 생성된 diff, 로그 요약, 테스트 결과, 메시지 id를 evidence로 수집한다.</li>
<li>실행 완료 시 <code>actual_effect</code>를 계산해 draft를 finalize한다.</li>
<li>finalized receipt를 lineage graph, 검색 인덱스, 감사 저장소에 동시 반영한다.</li>
</ol>
<p>이 구조의 장점은 실패도 receipt로 남는다는 점입니다. denied, expired, partial success도 다 기록해야 나중에 왜 중단됐는지 설명할 수 있습니다. 성공만 남기면 운영 데이터가 왜곡됩니다.</p>
<h3 id="4-receipt는-어디까지-자동-생성하고-어디서-사람이-개입해야-할까">4) receipt는 어디까지 자동 생성하고, 어디서 사람이 개입해야 할까</h3>
<p>현장에서 자주 나오는 오해는 receipt를 전부 사람이 정리해야 한다는 생각입니다. 실제로는 반대로 가는 편이 맞습니다. <strong>draft는 런타임이 자동 생성하고, 사람이 보는 것은 예외와 위험 신호만 남기는 구조</strong>가 운영 비용이 훨씬 낮습니다.</p>
<p>권장 분리는 아래와 같습니다.</p>
<ul>
<li>런타임 자동 생성: receipt_id, tool_action, started_at, completed_at, resource_scope, evidence_refs</li>
<li>정책 엔진 자동 평가: approval_ref 연결 여부, lease 만료 여부, expected/actual effect 차이, duplicate suppression hit 여부</li>
<li>사람 개입: partial success 원인 분류, 고위험 effect 승인, 롤백 승인, 예외 케이스 라벨링</li>
</ul>
<p>이렇게 나누면 receipt가 감사 문서가 아니라 <strong>실행 직후 품질 게이트</strong>로 동작합니다. 특히 외부 전송이나 운영 변경에서는 사람이 &ldquo;로그를 읽고 해석&quot;하기 전에 시스템이 먼저 &ldquo;설명 불가능한 실행인지&quot;를 판정해 주는 구조가 중요합니다.</p>
<p>간단한 예시는 아래처럼 생각할 수 있습니다.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#ff79c6">receipt_id</span>: rcpt_20260414_184200_01
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">intent_id</span>: task_2481
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">approval_ref</span>: appr_771
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">capability_lease_ref</span>: lease_msg_send_15m
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">tool_action</span>: telegram.send
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">resource_scope</span>:
</span></span><span style="display:flex;"><span>  - <span style="color:#ff79c6">channel</span>: partner-alerts
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">expected_effect</span>: <span style="color:#f1fa8c">&#34;장애 공지 1건 발송&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">actual_effect</span>: <span style="color:#f1fa8c">&#34;장애 공지 1건 발송, message_id=91827&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">evidence_refs</span>:
</span></span><span style="display:flex;"><span>  - <span style="color:#ff79c6">message_id</span>: <span style="color:#bd93f9">91827</span>
</span></span><span style="display:flex;"><span>  - <span style="color:#ff79c6">template_version</span>: outage_v3
</span></span><span style="display:flex;"><span>  - <span style="color:#ff79c6">approval_snapshot_hash</span>: sha256:...
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">outcome</span>: success
</span></span></code></pre></div><p>핵심은 스키마가 거창한가가 아니라, <strong>이 액션이 승인 범위 안에서 예측한 효과를 냈는지</strong>를 바로 비교할 수 있느냐입니다.</p>
<h3 id="5-4주-도입-플랜">5) 4주 도입 플랜</h3>
<p><strong>1주차: 고위험 액션 인벤토리화</strong><br>
외부 전송, 쓰기, 운영 변경, 권한 변경 액션을 분류하고 필수 evidence를 정합니다.</p>
<p><strong>2주차: 최소 receipt 스키마와 저장소 고정</strong><br>
receipt_id, intent_id, approval_ref, lease_ref, actual_effect, evidence_refs만 먼저 붙여도 충분합니다.</p>
<p><strong>3주차: 실행 경로 연결</strong><br>
코드 수정과 외부 전송 두 흐름에 receipt draft/finalize를 붙이고 duplicate suppression key를 도입합니다.</p>
<p><strong>4주차: 리뷰 화면과 경보 연결</strong><br>
unverifiable action, expired lease execution, evidence 누락을 즉시 경고로 올리고 사람이 receipt 기반으로 검토할 수 있게 만듭니다.</p>
<h2 id="트레이드오프주의점">트레이드오프/주의점</h2>
<ol>
<li>
<p><strong>receipt를 자세히 남길수록 비밀값과 개인정보가 섞일 위험이 커집니다.</strong><br>
원문 저장보다 digest, redaction, pointer 방식이 기본이어야 합니다.</p>
</li>
<li>
<p><strong>모든 액션을 동기식 receipt로 묶으면 경로가 느려질 수 있습니다.</strong><br>
핵심 필드만 동기 반영하고 evidence finalize는 짧은 비동기 후처리로 나누는 편이 낫습니다.</p>
</li>
<li>
<p><strong>스키마가 너무 일반적이면 사람이 읽어도 아무 의미가 없습니다.</strong><br>
<code>did something</code> 같은 outcome은 감사에는 남아도 운영에는 도움이 안 됩니다.</p>
</li>
<li>
<p><strong>receipt만 있고 lineage, lease, approval이 분리돼 있으면 절반짜리입니다.</strong><br>
receipt는 연결점이지 단독 솔루션이 아닙니다.</p>
</li>
</ol>
<h2 id="체크리스트-또는-연습">체크리스트 또는 연습</h2>
<h3 id="체크리스트">체크리스트</h3>
<ul>
<li><input disabled="" type="checkbox"> 외부 전송과 운영 변경 액션은 receipt coverage가 100%에 가깝다.</li>
<li><input disabled="" type="checkbox"> receipt에 approval_ref와 capability_lease_ref가 같이 들어간다.</li>
<li><input disabled="" type="checkbox"> expected_effect와 actual_effect를 분리해 기록한다.</li>
<li><input disabled="" type="checkbox"> duplicate suppression key 또는 replay guard가 있다.</li>
<li><input disabled="" type="checkbox"> evidence 누락과 expired lease execution을 별도 경보로 본다.</li>
</ul>
<h3 id="연습-과제">연습 과제</h3>
<ol>
<li>최근 에이전트 작업 3건을 골라 intent, approval, lease, actual effect, evidence를 표로 다시 정리해 보세요. 빠진 연결이 어디인지 바로 보일 가능성이 큽니다.</li>
<li>외부 전송 액션 하나를 골라 message id, 대상, 승인 ref, 발송 시각, 결과 상태를 묶은 최소 receipt 스키마를 설계해 보세요.</li>
<li>코드 수정 워크플로 하나에 duplicate suppression key를 넣는다면 어떤 조합이 적절한지 적어 보세요. 보통 <code>task_id + repo + branch + scope</code> 정도만으로도 중복 방지 품질이 크게 올라갑니다.</li>
</ol>
<h2 id="관련-글">관련 글</h2>
<ul>
<li><a href="/learning/deep-dive/deep-dive-execution-receipt-operations-playbook/">Execution Receipt 운영 플레이북</a></li>
<li><a href="/posts/2026-04-05-tool-permission-manifest-runtime-attestation-trend/">Tool Permission Manifest + Runtime Attestation</a></li>
<li><a href="/posts/2026-04-09-harness-engineering-agent-runtime-frame-trend/">Harness Engineering</a></li>
<li><a href="/posts/2026-04-10-test-evidence-pipeline-ai-change-review-trend/">Test Evidence Pipeline</a></li>
<li><a href="/posts/2026-04-11-stateful-sandbox-snapshot-environment-replay-trend/">Stateful Sandbox Snapshot</a></li>
<li><a href="/posts/2026-04-12-action-lineage-agent-observability-graph-trend/">Action Lineage Graph</a></li>
<li><a href="/posts/2026-04-13-capability-lease-expiring-agent-permissions-trend/">Capability Lease</a></li>
</ul>
]]></content:encoded></item><item><title>백엔드 커리큘럼 심화: Execution Receipt 운영 플레이북 (Approval·Lease·Evidence·Replay Guard)</title><link>https://jyukki.com/learning/deep-dive/deep-dive-execution-receipt-operations-playbook/</link><pubDate>Tue, 14 Apr 2026 00:00:00 +0000</pubDate><guid>https://jyukki.com/learning/deep-dive/deep-dive-execution-receipt-operations-playbook/</guid><description>에이전트가 외부 전송, 파일 수정, 운영 액션을 수행할 때 execution receipt를 어떤 순서로 설계하고 어떤 숫자로 운영해야 하는지 실무 플레이북 형태로 정리합니다.</description><content:encoded><![CDATA[<p>에이전트 운영이 읽기 중심일 때는 로그만 잘 남겨도 어느 정도 관리가 됩니다. 하지만 외부 메시지 전송, 코드 수정, 설정 변경, 운영 명령 실행처럼 실제 효과가 생기는 액션이 늘어나면 로그만으로는 부족합니다. 운영자는 곧바로 다른 질문을 하게 됩니다. <strong>이 액션은 왜 허용됐는가, 어떤 승인과 어떤 권한으로 실행됐는가, 원래 의도와 실제 결과가 같았는가, 재시도로 한 번 더 실행된 것은 아닌가</strong> 같은 질문입니다.</p>
<p>이때 필요한 것이 execution receipt입니다. receipt는 단순 로그 이벤트가 아니라, 작업 단위 액션을 설명 가능한 객체로 묶는 기록입니다. 저는 이를 <a href="/posts/2026-04-14-execution-receipt-agent-operations-trend/">Execution Receipt 트렌드 글</a>의 실무판이라고 보는 편이 맞다고 생각합니다. <a href="/posts/2026-04-12-action-lineage-agent-observability-graph-trend/">Action Lineage Graph</a>가 전체 실행 연결을 보여주고, <a href="/posts/2026-04-13-capability-lease-expiring-agent-permissions-trend/">Capability Lease</a>가 현재 권한 범위를 제한한다면, execution receipt는 <strong>이번 액션 하나가 어떤 계약 아래 실행됐고 어떤 증거를 남겼는지</strong>를 닫아 주는 마지막 고리입니다.</p>
<h2 id="이-글에서-얻는-것">이 글에서 얻는 것</h2>
<ul>
<li>execution receipt를 어떤 액션부터 붙여야 투자 대비 효과가 큰지 우선순위를 정할 수 있습니다.</li>
<li>approval, lease, evidence, replay guard를 한 레코드에 어떻게 묶어야 운영 설명 가능성이 올라가는지 이해할 수 있습니다.</li>
<li>coverage, unverifiable action rate, approval-to-receipt latency 같은 지표를 어떤 초기 목표값으로 운영할지 바로 가져갈 수 있습니다.</li>
</ul>
<h2 id="핵심-개념이슈">핵심 개념/이슈</h2>
<h3 id="1-receipt는-감사-로그가-아니라-실행-계약의-결과-레코드다">1) receipt는 감사 로그가 아니라 실행 계약의 결과 레코드다</h3>
<p>실무에서 receipt를 잘못 도입하면 &ldquo;로그를 더 많이 저장하는 프로젝트&quot;로 끝나기 쉽습니다. 하지만 receipt의 핵심은 보존량이 아닙니다. <strong>액션 하나를 intent, approval, capability, evidence, effect와 함께 설명 가능한 상태로 묶는 것</strong>이 본질입니다.</p>
<p>예를 들어 에이전트가 운영 채널에 공지 메시지를 보냈다면 최소한 아래 질문에 답할 수 있어야 합니다.</p>
<ul>
<li>이 메시지는 누가 요청했는가</li>
<li>사람이 승인했다면 어떤 승인 레퍼런스와 연결되는가</li>
<li>당시 허용된 capability lease는 무엇이었는가</li>
<li>실제 발송 대상과 message id는 무엇인가</li>
<li>동일 intent가 재시도로 두 번 발송된 것은 아닌가</li>
</ul>
<p>즉 receipt는 &ldquo;이벤트가 있었다&quot;를 넘어서 <strong>행동의 정당성과 결과를 한 번에 설명하는 최소 단위</strong>여야 합니다.</p>
<h3 id="2-최소-필드는-작아도-되지만-approval-lease-actual-effect는-반드시-같이-있어야-한다">2) 최소 필드는 작아도 되지만 approval, lease, actual effect는 반드시 같이 있어야 한다</h3>
<p>처음부터 거대한 스키마를 만들 필요는 없습니다. 다만 아래 필드는 거의 빠지면 안 됩니다.</p>
<ul>
<li><code>receipt_id</code></li>
<li><code>intent_id</code> 또는 <code>task_id</code></li>
<li><code>subject_id</code> 또는 <code>session_id</code></li>
<li><code>approval_ref</code></li>
<li><code>capability_lease_ref</code></li>
<li><code>tool_action</code></li>
<li><code>resource_scope</code></li>
<li><code>expected_effect</code></li>
<li><code>actual_effect</code></li>
<li><code>evidence_refs</code></li>
<li><code>outcome</code></li>
<li><code>started_at</code>, <code>completed_at</code></li>
<li><code>replay_guard_key</code></li>
</ul>
<p>여기서 특히 중요한 것은 <code>expected_effect</code>와 <code>actual_effect</code>를 분리하는 것입니다. 승인 당시 기대 효과는 &ldquo;문서 2개 수정&quot;인데 실제 효과가 &ldquo;문서 2개 수정 + 설정 파일 변경&quot;이라면, receipt가 있어야 범위 초과를 바로 탐지할 수 있습니다. approval과 lease를 따로 저장하는 것만으로는 부족한 이유가 여기에 있습니다. <strong>승인 근거와 실제 결과가 한 곳에서 비교돼야 자동 판정이 가능해집니다.</strong></p>
<h3 id="3-우선순위는-고위험-쓰기-액션부터-붙이는-편이-가장-안전하다">3) 우선순위는 고위험 쓰기 액션부터 붙이는 편이 가장 안전하다</h3>
<p>receipt를 모든 액션에 한꺼번에 붙이려 하면 오래 걸리고, 운영팀 피로만 늘어납니다. 초반 우선순위는 아래처럼 잡는 편이 좋습니다.</p>
<ol>
<li>외부 전송, 운영 명령, 권한 변경</li>
<li>코드/문서 수정</li>
<li>배치 트리거, 설정 변경, 데이터 쓰기</li>
<li>읽기 전용 조사 액션</li>
</ol>
<p>이 순서가 좋은 이유는 복구 난이도와 설명 책임이 정확히 이 순서로 커지기 때문입니다. 외부 전송은 취소가 어렵고, 운영 명령은 영향 범위가 넓고, 코드 변경은 diff와 테스트 증거를 붙이기 쉬워서 빠르게 효과를 볼 수 있습니다. 반면 읽기 전용 액션은 나중에 coverage를 넓힐 때 포함해도 됩니다.</p>
<h3 id="4-replay-guard가-없으면-receipt는-예쁘지만-운영-사고는-계속-난다">4) replay guard가 없으면 receipt는 예쁘지만 운영 사고는 계속 난다</h3>
<p>많은 팀이 receipt 스키마는 만들지만 재시도 중복을 막는 키를 빼먹습니다. 그러면 감사 설명은 그럴듯해도 운영 사고는 계속 납니다. timeout이나 worker 재시작 뒤 같은 intent가 다시 실행되면, receipt는 두 장 생기고 실제 효과도 두 번 발생할 수 있기 때문입니다.</p>
<p>그래서 <code>replay_guard_key</code> 또는 duplicate suppression key를 필수 필드로 두는 편이 좋습니다. 보통 아래 조합이면 출발점으로 충분합니다.</p>
<ul>
<li>외부 전송: <code>intent_id + destination + template_version</code></li>
<li>코드 수정: <code>task_id + repo + branch + scope</code></li>
<li>운영 명령: <code>intent_id + service + action + target_env</code></li>
</ul>
<p>중요한 것은 키가 완벽히 보편적일 필요는 없다는 점입니다. 먼저 <strong>같은 효과를 두 번 내면 안 되는 액션</strong>에만 붙여도 사고율이 크게 떨어집니다.</p>
<h3 id="5-좋은-receipt-파이프라인은-draft와-finalize를-분리한다">5) 좋은 receipt 파이프라인은 draft와 finalize를 분리한다</h3>
<p>실행 직전에 receipt draft를 만들고, 실행 후 evidence를 수집해 finalize하는 구조가 가장 단순합니다.</p>
<ol>
<li>intent 생성</li>
<li>approval 연결</li>
<li>capability lease 발급 또는 참조</li>
<li>tool action 직전 receipt draft 생성</li>
<li>실행 결과와 evidence 수집</li>
<li>actual effect 계산</li>
<li>receipt finalize 및 경보 평가</li>
</ol>
<p>이 구조의 장점은 실패도 같은 형태로 남길 수 있다는 점입니다. denied, expired, partial success도 모두 receipt로 저장하면 운영 데이터 왜곡이 줄어듭니다. 성공만 남기면 coverage는 높아 보여도 실제 설명 가능성은 낮습니다.</p>
<h2 id="실무-적용">실무 적용</h2>
<h3 id="1-권장-초기-목표값">1) 권장 초기 목표값</h3>
<p>처음 운영할 때는 아래 숫자가 무난한 출발점입니다.</p>
<ul>
<li>외부 전송, 운영 변경, 권한 변경: receipt coverage <strong>100%</strong></li>
<li>코드/문서 수정: receipt coverage <strong>95% 이상</strong></li>
<li><code>unverifiable_action_rate</code>: <strong>0.1% 미만</strong></li>
<li><code>approval_to_receipt_p95</code>: <strong>60초 미만</strong></li>
<li><code>evidence_completeness_ratio</code>: <strong>95% 이상</strong></li>
<li><code>duplicate_execution_rate</code>: <strong>0.5% 미만</strong></li>
</ul>
<p>이 숫자의 핵심은 완벽한 자동화가 아닙니다. <strong>설명 불가능한 실행을 먼저 줄이는 것</strong>이 목표입니다.</p>
<h3 id="2-팀-역할-분리-기준">2) 팀 역할 분리 기준</h3>
<ul>
<li>플랫폼 팀: receipt 스키마, 저장소, policy evaluator, replay guard 제공</li>
<li>제품/도메인 팀: expected effect 정의, 고위험 액션 분류, evidence 최소 세트 정의</li>
<li>운영자/리뷰어: partial success 분류, 롤백 승인, 예외 정책 검토</li>
</ul>
<p>이 분리가 없으면 플랫폼은 과도하게 추상적인 필드만 만들고, 도메인 팀은 사람이 읽어도 의미 없는 outcome만 남기게 됩니다.</p>
<h3 id="3-실제-점검-체크리스트">3) 실제 점검 체크리스트</h3>
<ul>
<li><input disabled="" type="checkbox"> 외부 전송 액션은 모두 approval_ref와 message id를 같이 남긴다.</li>
<li><input disabled="" type="checkbox"> 코드 수정 액션은 diff hash 또는 commit ref를 evidence로 남긴다.</li>
<li><input disabled="" type="checkbox"> lease 만료 후 발생한 actual effect는 무조건 실패 receipt와 경보로 승격한다.</li>
<li><input disabled="" type="checkbox"> replay guard hit는 success가 아니라 duplicate-skipped 같은 별도 outcome으로 구분한다.</li>
<li><input disabled="" type="checkbox"> expected effect와 actual effect 차이가 있으면 사람이 보게 되는 review queue로 보낸다.</li>
</ul>
<h2 id="트레이드오프주의점">트레이드오프/주의점</h2>
<p>첫째, evidence를 너무 자세히 저장하면 비밀값이나 개인정보가 섞일 수 있습니다. 원문보다 hash, pointer, redaction을 기본값으로 두는 편이 안전합니다.</p>
<p>둘째, 모든 것을 동기식으로 finalize하면 쓰기 경로가 느려집니다. 핵심 필드만 동기 반영하고, 세부 evidence 보강은 짧은 비동기 후처리로 넘기는 편이 좋습니다.</p>
<p>셋째, 스키마를 너무 일반화하면 사람이 읽어도 의미가 없습니다. <code>did something</code> 같은 outcome은 저장 비용만 늘리고 운영 판단에는 거의 도움이 되지 않습니다.</p>
<h2 id="관련-글">관련 글</h2>
<ul>
<li><a href="/posts/2026-04-14-execution-receipt-agent-operations-trend/">Execution Receipt 트렌드 글</a></li>
<li><a href="/posts/2026-04-12-action-lineage-agent-observability-graph-trend/">Action Lineage Graph</a></li>
<li><a href="/posts/2026-04-13-capability-lease-expiring-agent-permissions-trend/">Capability Lease</a></li>
<li><a href="/posts/2026-04-10-test-evidence-pipeline-ai-change-review-trend/">Test Evidence Pipeline</a></li>
</ul>
]]></content:encoded></item></channel></rss>