<!-- task=m-stream-evidence-gate-core/07+01,06_commit_boundary plan=1 tag=REVIEW_API -->

# Stream Gate Commit Boundary와 Release Integration 후속 구현 계획

## 이 파일을 읽는 구현 에이전트에게

- 아래 구현 체크리스트와 검증 명령을 수행하고 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션에 실제 변경 내용과 stdout/stderr를 기록한다.
- active PLAN/CODE_REVIEW 파일을 유지한 채 review-ready만 보고한다. 판정, 로그 아카이브, `complete.log`, task 디렉터리 이동은 code-review skill 전용이다.
- 막히면 정확한 blocker, 시도한 명령과 출력, 재개 조건만 구현 소유 evidence에 기록한다.
- 사용자에게 질문하거나 선택지를 제시하지 않고, user-input 도구·control-plane stop 파일·다음 상태 분류를 만들지 않는다.

## 배경

이전 루프는 계획된 commit boundary와 release integration 코드·테스트가 전혀 생성되지 않아 FAIL로 끝났다. 현재 `EvidenceTail` 선행 작업은 완료됐으므로 request-scope `CommitBoundary`와 progress-aware `StreamReleaser`를 실제 구현해 partial write와 cursor를 일치시켜야 한다. S03/S04/S05/S17/S19의 start staging, attempt 교체, cancel-before-terminal, single terminal을 네 신규 파일 안에서 닫는다.

## Archive Evidence Snapshot

- 이전 계획 로그: `agent-task/m-stream-evidence-gate-core/07+01,06_commit_boundary/plan_local_G06_0.log`
- 이전 리뷰 로그: `agent-task/m-stream-evidence-gate-core/07+01,06_commit_boundary/code_review_local_G07_0.log`
- 이전 판정: `FAIL`
- Required:
  - `packages/go/streamgate/commit_boundary.go`와 `packages/go/streamgate/stream_release.go`가 없어 staged response-start, monotonic state, partial confirmation, attempt replacement, cancel→terminal 동작이 구현되지 않았다.
  - `packages/go/streamgate/commit_boundary_test.go`와 `packages/go/streamgate/stream_release_test.go`가 없고 target test inventory가 비어 S03/S04/S05/S17/S19와 zero/partial/full progress, exactly-once/race를 검증하지 못했다.
  - 이전 review stub의 구현 체크리스트와 검증 결과가 전부 미완료였으므로 실제 stdout/stderr, 설계 결정, 계획 대비 변경 증거가 필요하다.
- Suggested: 없음
- Nit: 없음
- 현재 재확인: 위 네 대상 파일은 모두 없고 `go test -list '^(TestCommitBoundary|TestStreamReleaser)' ./packages/go/streamgate`는 대상 테스트를 열거하지 않았다.
- 선행 완료:
  - `agent-task/archive/2026/07/m-stream-evidence-gate-core/01_event_contract_types/complete.log`
  - `agent-task/archive/2026/07/m-stream-evidence-gate-core/06+01_evidence_tail/complete.log`
- 현재 baseline: host Go `go1.26.2`, `go test -count=1 ./packages/go/streamgate`, `go test -race -count=1 ./packages/go/streamgate`, `go vet ./packages/go/streamgate`가 PASS했다.
- 구현자는 위 특정 로그 외의 `agent-task/archive/**`를 넓게 탐색하지 않는다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/stream-evidence-gate-core.md`
- Milestone link: [Milestone 문서](agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/stream-evidence-gate-core.md)
- Task ids:
  - `evidence-tail`: predecessor S01/S02 evidence와 S19 overflow cancel/terminal 통합
  - `commit-boundary`: staged response-start, irreversible release state와 single terminal
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `packages/go/streamgate/event.go`
- `packages/go/streamgate/filter_contract.go`
- `packages/go/streamgate/terminal.go`
- `packages/go/streamgate/evidence_tail.go`
- `packages/go/streamgate/terminal_test.go`
- `packages/go/streamgate/evidence_tail_test.go`
- `packages/go/streamgate/consumer_contract_test.go`
- `go.mod`
- `agent-ops/rules/project/domain/platform-common/rules.md`
- `agent-ops/rules/project/domain/testing/rules.md`
- `agent-ops/rules/common/rules-agent-spec.md`
- `agent-test/local/rules.md`
- `agent-test/local/platform-common-smoke.md`
- `agent-spec/index.md`
- `agent-contract/index.md`
- `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/stream-evidence-gate-core.md`
- `agent-roadmap/sdd/knowledge-tool-optimization-extension/stream-evidence-gate-core/SDD.md`
- `agent-task/archive/2026/07/m-stream-evidence-gate-core/01_event_contract_types/complete.log`
- `agent-task/archive/2026/07/m-stream-evidence-gate-core/06+01_evidence_tail/complete.log`
- `agent-task/m-stream-evidence-gate-core/07+01,06_commit_boundary/plan_local_G06_0.log`
- `agent-task/m-stream-evidence-gate-core/07+01,06_commit_boundary/code_review_local_G07_0.log`
- `.gitignore`

### SDD 기준

- SDD: `agent-roadmap/sdd/knowledge-tool-optimization-extension/stream-evidence-gate-core/SDD.md`
- 상태: `[승인됨]`; Milestone 구현 잠금 `해제`, 결정 필요 `없음`.
- `S03` / Task `commit-boundary` / Evidence Map: terminal-before-evidence에서 eager start/output 없이 safe outcome 또는 terminal error를 한 번만 commit한다.
- `S04` / Task `commit-boundary` / Evidence Map: idle timeout은 pending을 release하지 않고 terminal error만 commit한다.
- `S05` / Task `commit-boundary` / Evidence Map: `stream_open` 뒤 exact/schema rollback을 막고 continuation-safe만 허용한다.
- `S17` / Task `commit-boundary` / Evidence Map: original attempt start를 숨기고 selected retry start/output만 한 번 노출한다.
- `S19` / Task `evidence-tail` / Evidence Map: hard overflow는 partial/start release 없이 attempt cancel 뒤 terminal error로 끝낸다.
- S01/S02의 bounded rune/look-behind evidence는 완료된 `06+01_evidence_tail/complete.log`에서 이어받는다. 위 행이 구현 체크리스트의 staging/state matrix, progress confirmation, replacement/fail-pending fixture와 최종 race 검증을 결정했다.

### 테스트 환경 규칙

- `test_env`: local
- `agent-test/local/rules.md`와 매칭 profile `agent-test/local/platform-common-smoke.md`를 읽고 host toolchain, fresh package test, race, vet, proto/transport 검증 규칙을 적용했다.
- 현재 toolchain: `/config/.local/bin/go` → `/config/opt/go/bin/go`, `go1.26.2 linux/arm64`, `GOROOT=/config/opt/go`.
- fresh 결과: `go test -count=1 ./packages/go/streamgate` PASS; race 결과: `go test -race -count=1 ./packages/go/streamgate` PASS; vet PASS.
- Go test cache는 새 동시성/ordering 구현의 증거로 허용하지 않으므로 모든 결정 명령에 `-count=1`을 사용한다.
- Edge/Node transport unit은 선행 로그에서 host GOROOT의 `crypto/internal/fips140cache` 누락 setup blocker가 기록됐다. 우회하지 않고 재실행하며 같은 환경 오류면 원문과 host Go 설치 복구 조건을 기록한다. 이 task는 production transport adapter를 바꾸지 않아 focused package/race/vet가 구현 판정의 결정 증거다.
- external runner, secret, runtime identity, port, remote checkout은 필요 없다. test-rule 문서 유지보수도 이 task 범위에는 필요 없다.

### 테스트 커버리지 공백

- `ResponseStart`와 `ReleaseSink` 자체 계약 테스트는 있으나 stage만으로 sink를 호출하지 않고 첫 safe release에서 start가 정확히 한 번 선행하는 boundary 테스트가 없다.
- `EvidenceTail` zero/partial/full confirm 테스트는 있으나 실제 sink 성공 event 수와 `ReleaseConfirmation`을 연결하는 owner와 통합 테스트가 없다.
- start/release/terminal sink 오류가 반환한 state와 이미 성공한 progress를 보존하는 state regression 테스트가 없다.
- original attempt를 uncommitted에서만 교체하고 tail generation까지 함께 reset하는 테스트가 없다.
- idle/overflow에서 pending/start release 0, cancel-before-terminal, cancel failure의 bounded cause, terminal exactly once 테스트가 없다.
- concurrent release/terminal/replacement 직렬화와 race 검증이 없다.

### 심볼 참조

- rename/remove 없음.
- 새 public symbol: `CommitBoundary`, `ReleaseProgress`, `StreamReleaser`, `AttemptCanceller`, `NewCommitBoundary`, `NewStreamReleaser`.
- `ReleaseSink` 현재 구현/호출 증거:
  - `packages/go/streamgate/terminal_test.go:573-652`의 `fakeReleaseSink`와 compile contract test.
  - `packages/go/streamgate/consumer_contract_test.go:194-222,743-1059`의 `fakeHostReleaseSink`와 direct terminal framing test.
- `PreparedRelease`/`ReleaseConfirmation`은 `packages/go/streamgate/evidence_tail_test.go`에서만 직접 소비되며 production orchestrator는 아직 없다.
- 매칭되는 active agent-spec/agent-contract 문서는 없고 외부 API, wire, event/config schema는 변경하지 않는다.
- 새 import는 Go 표준 라이브러리 `context`, `errors`, `fmt`, `sync` 범위이며 `go.mod` 의존성 추가는 없다.

### 분할 판단

- split decision policy를 plan 파일 선택 전에 평가했다.
- 현재 subtask `07+01,06_commit_boundary`의 predecessor `01`은 `agent-task/archive/2026/07/m-stream-evidence-gate-core/01_event_contract_types/complete.log`, `06`은 `agent-task/archive/2026/07/m-stream-evidence-gate-core/06+01_evidence_tail/complete.log`로 모두 충족됐다.
- commit state, sink progress, evidence confirm, attempt replacement와 fail-pending은 동일 request의 irreversible ordering을 공유한다. API와 tests를 나누면 partial confirm 또는 S19 cancel→terminal 중 한쪽만으로 PASS할 수 없어 독립 검토 단위가 되지 않는다.
- production Edge/OpenAI adapter rollout은 별도 ownership/verification boundary라 이 task와 합치지 않는다. 따라서 네 신규 파일을 한 subtask로 유지하는 것이 안전하다.

### 범위 결정 근거

- 수정 범위는 `packages/go/streamgate/commit_boundary.go`, `commit_boundary_test.go`, `stream_release.go`, `stream_release_test.go`와 구현 evidence를 채우는 현재 task 디렉터리다.
- `event.go`, `terminal.go`, `filter_contract.go`, `evidence_tail.go`의 기존 public 계약은 소비만 하고 수정하지 않는다.
- Edge/OpenAI handler의 eager write 제거, production `ReleaseSink`/`AttemptCanceller` adapter, coordinator/arbiter/recovery budget, semantic filter, config/proto/API 변경은 후속 consumer adoption 범위다.
- `CommitAllowsStrategy`는 commit state 축만 판정하며 capability, terminal/tool side effect, budget 조건을 대신하지 않는다.

### 최종 라우팅

- evaluation_mode: `isolated-reassessment`
- build:
  - closures: `scope_closed=true`, `context_closed=true`, `verification_closed=true`, `evidence_trusted=true`, `ownership_closed=true`, `decision_closed=true`
  - closure basis: 네 신규 파일과 기존 sink/tail 계약으로 정확성 범위가 닫히고, completed predecessor 및 current package/race/vet 출력이 재현 가능하며, 병행 작업은 write path가 겹치지 않고 Milestone 결정 필요가 없다.
  - scores: `scope_coupling=2`, `state_concurrency=2`, `blast_irreversibility=1`, `evidence_diagnosis=0`, `verification_complexity=1`
  - result: lane `local`, grade `G06`, filename `PLAN-local-G06.md`
- review:
  - closures: `scope_closed=true`, `context_closed=true`, `verification_closed=true`, `evidence_trusted=true`, `ownership_closed=true`, `decision_closed=true`
  - closure basis: state/order/cursor를 fake sink/canceller와 fresh/race 검증으로 함께 판정할 수 있고 외부 서비스나 사용자 결정이 필요 없다.
  - scores: `scope_coupling=2`, `state_concurrency=2`, `blast_irreversibility=1`, `evidence_diagnosis=1`, `verification_complexity=1`
  - result: lane `local`, grade `G07`, filename `CODE_REVIEW-local-G07.md`

## 구현 체크리스트

- [ ] `REVIEW_API-1` attempt-scoped staged response-start, monotonic sink state, progress 보존, body 없는 success와 exactly-once terminal을 가진 request-scope `CommitBoundary`를 구현·테스트한다.
- [ ] `REVIEW_API-2` prepared evidence와 sink `ReleaseProgress`를 직렬화해 zero/partial/full 성공 수만 cursor에 confirm하는 `StreamReleaser`를 구현·테스트한다.
- [ ] `REVIEW_API-3` boundary와 tail을 함께 묶은 uncommitted attempt replacement, idle/overflow discard, cancel→terminal/no-release와 state-only recovery matrix를 구현·테스트한다.
- [ ] `REVIEW_API-4` host Go focused/fresh/race/vet와 공통 profile 검증을 실행하고 생성물·diff hygiene 및 환경 blocker를 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다.

### [REVIEW_API-1] Request-scope staging과 monotonic sink state

- 문제:
  - `packages/go/streamgate/terminal.go:13-36`은 commit enum만 정의하고 request 전이 owner가 없다.
  - `packages/go/streamgate/terminal.go:550-562`의 sink seam은 eager/duplicate start, state regression, duplicate terminal을 자체 방지하지 않는다.
- 해결 방법:
  - `commit_boundary.go`에 `CommitBoundary`, immutable `ReleaseProgress`, constructor와 state/attempt APIs를 만든다.
  - boundary가 sink, mutex/condition, current attempt ID, staged start, monotonic `CommitState`, in-flight reservation을 소유한다. mutex 아래에서 입력·전이를 reserve하되 외부 sink callback 동안 lock을 잡지 않고 완료 시 반환 state와 성공 progress를 원자적으로 반영한다.
  - `BeginAttempt`와 `StageResponseStart`는 `transport_uncommitted`에서만 동작하고 stage 시 sink call은 0회다. `ReleaseSafe`는 staged start를 먼저 최대 한 번 commit한 다음 ordered event를 하나씩 release한다.
  - sink state는 `transport_uncommitted` → `stream_open` → `terminal_committed`만 허용한다. error와 함께 유효한 전진 state가 반환되면 state는 보존하되 실패 event는 confirmed progress에 포함하지 않는다. unknown/regression state는 stable error다.
  - success terminal은 body가 없어도 staged start를 먼저 commit하고 terminal을 한 번 commit한다. uncommitted error terminal은 staged start를 버리고 terminal만 commit한다. concurrent terminal reservation 중 하나만 sink에 도달한다.
- Before (`packages/go/streamgate/terminal.go:550-562`):

```go
type ReleaseSink interface {
	CommitResponseStart(ctx context.Context, rs ResponseStart) (CommitState, error)
	Release(ctx context.Context, ev ReleaseEvent) (CommitState, error)
	CommitTerminal(ctx context.Context, tr TerminalResult) (CommitState, error)
}
```

- After (`packages/go/streamgate/commit_boundary.go`):

```go
import (
	"context"
	"errors"
	"fmt"
	"sync"
)

func NewCommitBoundary(sink ReleaseSink) (*CommitBoundary, error)
func (b *CommitBoundary) BeginAttempt(attemptID string) error
func (b *CommitBoundary) StageResponseStart(attemptID string, start ResponseStart) error
func (b *CommitBoundary) ReleaseSafe(ctx context.Context, attemptID string, events []ReleaseEvent) (ReleaseProgress, error)
func (b *CommitBoundary) CommitTerminal(ctx context.Context, attemptID string, result TerminalResult) error
func (b *CommitBoundary) State() CommitState
```

- 수정 파일 및 체크리스트:
  - [ ] `packages/go/streamgate/commit_boundary.go`: constructor, immutable progress accessors, attempt/start staging, non-locking sink reservation, state validation, partial progress, empty success, terminal exactly once
  - [ ] `packages/go/streamgate/commit_boundary_test.go`: no eager call, start/event order, returned-state/error table, partial progress, empty success, concurrent terminal, callback state access
- 테스트 작성:
  - `TestCommitBoundaryStagesUntilFirstSafeRelease`: stage call 0회와 first release의 start→event order/단일 start를 검증한다.
  - `TestCommitBoundaryPreservesProgressAndMonotonicState`: start/body 단계별 성공·오류·unknown/regression table과 successful event count를 검증한다.
  - `TestCommitBoundaryCommitsEmptySuccessAndTerminalOnce`: body 없는 success와 concurrent terminal exactly once, callback 중 `State()` deadlock 부재를 검증한다.
- 중간 검증:
  - `go test -race -count=1 ./packages/go/streamgate -run '^TestCommitBoundary(StagesUntilFirstSafeRelease|PreservesProgressAndMonotonicState|CommitsEmptySuccessAndTerminalOnce)$'`
  - 기대 결과: PASS, race 없음.

### [REVIEW_API-2] Evidence prepare/confirm와 sink progress 통합

- 문제:
  - `packages/go/streamgate/evidence_tail.go:1443-1469`은 prepared snapshot/token을 제공하고 `1482-1530`, `1547-1656`은 prepare/confirm을 분리하지만 실제 sink 성공 수를 confirmation에 연결하는 production owner가 없다.
  - zero/partial/full sink failure에서 confirm 수가 실제 write와 다르면 cursor가 중복되거나 유실된다.
- 해결 방법:
  - `StreamReleaser`가 `EvidenceTail`과 `CommitBoundary`를 소유 참조하고 하나의 serializer로 `PrepareRelease` → `ReleaseSafe` → `ConfirmRelease`를 직렬화한다. tail은 자체 concurrency guard가 없으므로 releaser API 사이의 직접 tail mutation 금지를 문서화하고 tests에서 동일 owner를 사용한다.
  - boundary가 error와 함께 반환한 `ReleasedEvents()`가 0보다 크면 그 성공 수만 `ConfirmRelease`한다. 현재 실패 event는 progress에 넣지 않고 unconfirmed suffix를 남긴다.
  - confirmation failure는 자동 재전송하지 않고 stable error를 반환한다. duplicate/concurrent epoch 호출은 한 번만 sink에 도달하고 event order를 유지한다.
  - `ReleaseTerminalEpoch`은 safe snapshot의 confirmation이 성공한 뒤에만 success terminal을 commit한다. empty success는 boundary의 direct `CommitTerminal` 경로로 처리해 `PrepareRelease`의 empty-snapshot 거부와 섞지 않는다.
- Before (`packages/go/streamgate/evidence_tail.go:1482-1486,1547-1552`):

```go
func (t *EvidenceTail) PrepareRelease(epochID uint64) (PreparedRelease, error) {
	// ...
}

func (t *EvidenceTail) ConfirmRelease(token string, confirmation ReleaseConfirmation) error {
	// ...
}
```

- After (`packages/go/streamgate/stream_release.go`):

```go
import (
	"context"
	"errors"
	"fmt"
	"sync"
)

func NewStreamReleaser(tail *EvidenceTail, boundary *CommitBoundary, canceller AttemptCanceller) (*StreamReleaser, error)
func (r *StreamReleaser) ReleaseEpoch(ctx context.Context, attemptID string, epochID uint64) (ReleaseProgress, error)
func (r *StreamReleaser) ReleaseTerminalEpoch(ctx context.Context, attemptID string, epochID uint64, result TerminalResult) (ReleaseProgress, error)
```

- 수정 파일 및 체크리스트:
  - [ ] `packages/go/streamgate/stream_release.go`: serialized prepare→release→confirm, partial confirmation, terminal-after-confirm, duplicate protection, stable error wrapping
  - [ ] `packages/go/streamgate/stream_release_test.go`: zero/partial/full sink progress, cursor/pending/look-behind, terminal outcome exclusivity, event order, duplicate/concurrent epoch
- 테스트 작성:
  - `TestStreamReleaserConfirmsExactlySinkProgress`: zero/partial/full table에서 confirmed cursor와 suffix가 sink success count와 일치하는지 검증한다.
  - `TestStreamReleaserTerminalBeforeEvidenceExposesOneOutcome`: pass는 safe start/output+success terminal, error path는 pending/start 없이 error terminal만 한 번 노출하는지 검증한다.
  - `TestStreamReleaserDoesNotDuplicatePreparedRelease`: repeated/concurrent epoch 호출이 downstream event를 중복하지 않는지 검증한다.
- 중간 검증:
  - `go test -race -count=1 ./packages/go/streamgate -run '^TestStreamReleaser(ConfirmsExactlySinkProgress|TerminalBeforeEvidenceExposesOneOutcome|DoesNotDuplicatePreparedRelease)$'`
  - 기대 결과: PASS, race 없음.

### [REVIEW_API-3] Attempt replacement, idle와 overflow terminal

- 문제:
  - `packages/go/streamgate/filter_contract.go:323-344`은 recovery strategy enum만 제공해 commit state별 exact/schema/continuation 가능 여부를 강제하지 않는다.
  - `packages/go/streamgate/evidence_tail.go:1661-1693`의 replace/continuation/discard 전이는 boundary attempt와 원자적으로 연결되지 않는다.
  - S04/S19는 pending/start를 release하지 않고 provider attempt cancel 뒤 error terminal 한 번으로 끝내야 한다.
- 해결 방법:
  - boundary의 `ReplaceUncommittedAttempt`는 current old attempt와 uncommitted state에서만 staged start를 폐기하고 새 attempt를 연다. `StreamReleaser.ReplaceUncommittedAttempt`가 같은 serializer 아래 boundary 교체 성공 후 `tail.ResetForReplace()`를 호출해 두 generation을 함께 바꾼다.
  - `CommitAllowsStrategy`는 exact/schema=`transport_uncommitted`, continuation=`transport_uncommitted|stream_open`, terminal=`false`인 state-only matrix를 제공한다.
  - `AttemptCanceller.CancelAttempt(ctx, attemptID)`를 좁은 host seam으로 정의한다. `FailPending`은 error `TerminalResult`만 받고 tail pending/prepared token을 discard한 뒤 cancel을 호출하고 마지막에 boundary terminal을 commit한다.
  - cancel failure여도 release/retry하지 않고 `attempt_cancel_failed` bounded cause를 원래 error terminal에 append한 뒤 같은 single terminal로 끝낸다.
- Before (`packages/go/streamgate/evidence_tail.go:1661-1693`):

```go
func (t *EvidenceTail) ResetForReplace() { /* invalidates pending and prepared releases */ }
func (t *EvidenceTail) PrepareContinuation() { /* preserves committed cursor/look-behind */ }
func (t *EvidenceTail) DiscardPendingForTerminal() { /* drops pending before terminal */ }
```

- After (`packages/go/streamgate/commit_boundary.go`, `packages/go/streamgate/stream_release.go`):

```go
func (b *CommitBoundary) ReplaceUncommittedAttempt(oldAttemptID, newAttemptID string) error
func (b *CommitBoundary) CommitAllowsStrategy(strategy RecoveryStrategy) bool

type AttemptCanceller interface {
	CancelAttempt(context.Context, string) error
}

func (r *StreamReleaser) ReplaceUncommittedAttempt(oldAttemptID, newAttemptID string) error
func (r *StreamReleaser) FailPending(ctx context.Context, attemptID string, result TerminalResult) error
```

- 수정 파일 및 체크리스트:
  - [ ] `packages/go/streamgate/commit_boundary.go`: uncommitted-only attempt replacement와 state-only recovery matrix
  - [ ] `packages/go/streamgate/commit_boundary_test.go`: original/final start exposure, invalid post-open replace, exact/schema/continuation table
  - [ ] `packages/go/streamgate/stream_release.go`: coordinated tail reset, pending discard, cancel-before-terminal, bounded cancel failure cause
  - [ ] `packages/go/streamgate/stream_release_test.go`: S04/S17/S19 fixture와 exact call ordering
- 테스트 작성:
  - `TestCommitBoundaryReplacesOnlyUncommittedAttempt`: original start를 숨기고 final attempt start/output만 노출하며 post-open replacement를 거부하는지 검증한다.
  - `TestCommitBoundaryCommitStrategyMatrix`: 세 commit state와 세 strategy의 허용 표를 검증한다.
  - `TestStreamReleaserReplacementResetsTailGeneration`: boundary attempt와 tail pending/prepared token이 함께 교체되는지 검증한다.
  - `TestStreamReleaserIdleReleasesNoPending`: idle error에서 release/start 0, cancel→terminal 순서를 검증한다.
  - `TestStreamReleaserOverflowCancelsBeforeSingleTerminal`: S19 overflow에서 no partial release, cancel failure cause, terminal exactly once를 검증한다.
- 중간 검증:
  - `go test -race -count=1 ./packages/go/streamgate -run '^Test(CommitBoundary(ReplacesOnlyUncommittedAttempt|CommitStrategyMatrix)|StreamReleaser(ReplacementResetsTailGeneration|IdleReleasesNoPending|OverflowCancelsBeforeSingleTerminal))$'`
  - 기대 결과: PASS, race 없음.

### [REVIEW_API-4] 검증과 변경 범위 폐쇄

- 문제:
  - 이전 review stub의 모든 검증 결과가 `_미실행_`이어서 구현·테스트·race·profile 신뢰성이 없었다.
- 해결 방법:
  - host Go identity를 먼저 기록하고 focused test, full fresh/race/vet, proto/transport profile, diff hygiene를 순서대로 실행한다.
  - transport가 동일 host GOROOT setup error로 막히면 우회하지 않고 원문, exit code, `/config/opt/go` 복구 조건을 review evidence에 남긴다.
  - target 네 파일과 현재 task evidence 외의 병행 변경은 수정·정리하지 않는다.
- Before (`agent-task/m-stream-evidence-gate-core/07+01,06_commit_boundary/code_review_local_G07_0.log:141-210`):

```text
결과:
_미실행_
```

- After (`CODE_REVIEW-local-G07.md`):

```text
결과:
<실제 stdout/stderr와 exit code>
```

- 수정 파일 및 체크리스트:
  - [ ] `agent-task/m-stream-evidence-gate-core/07+01,06_commit_boundary/CODE_REVIEW-local-G07.md`: 완료 표, 체크리스트, 변경·설계 결정, 모든 실제 검증 출력
  - [ ] `proto/gen/iop`: `make proto` 전후 예상치 못한 diff가 없는지 확인하고 수정하지 않음
- 테스트 작성:
  - 별도 test 파일은 추가하지 않는다. REVIEW_API-1~3의 정상·경계·동시성 tests와 아래 final commands가 closure evidence다.
- 중간 검증:
  - `git diff --check -- packages/go/streamgate/commit_boundary.go packages/go/streamgate/commit_boundary_test.go packages/go/streamgate/stream_release.go packages/go/streamgate/stream_release_test.go agent-task/m-stream-evidence-gate-core/07+01,06_commit_boundary`
  - 기대 결과: stdout 없음.

## 의존 관계 및 구현 순서

1. predecessor `01`은 `agent-task/archive/2026/07/m-stream-evidence-gate-core/01_event_contract_types/complete.log`로 충족됐다.
2. predecessor `06`은 `agent-task/archive/2026/07/m-stream-evidence-gate-core/06+01_evidence_tail/complete.log`로 충족됐다.
3. `REVIEW_API-1` boundary state machine, `REVIEW_API-2` evidence progress integration, `REVIEW_API-3` coordinated recovery/failure ordering, `REVIEW_API-4` final verification 순으로 진행한다.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `packages/go/streamgate/commit_boundary.go` | REVIEW_API-1, REVIEW_API-3 |
| `packages/go/streamgate/commit_boundary_test.go` | REVIEW_API-1, REVIEW_API-3 |
| `packages/go/streamgate/stream_release.go` | REVIEW_API-2, REVIEW_API-3 |
| `packages/go/streamgate/stream_release_test.go` | REVIEW_API-2, REVIEW_API-3 |
| `agent-task/m-stream-evidence-gate-core/07+01,06_commit_boundary/CODE_REVIEW-local-G07.md` | REVIEW_API-4 |

## 최종 검증

1. `command -v go && readlink -f "$(command -v go)" && go version && go env GOROOT`
   - 기대 결과: PATH의 host Go와 실제 경로/GOROOT가 기록됨.
2. `gofmt -d packages/go/streamgate/commit_boundary.go packages/go/streamgate/commit_boundary_test.go packages/go/streamgate/stream_release.go packages/go/streamgate/stream_release_test.go`
   - 기대 결과: stdout 없음.
3. `go test -count=1 ./packages/go/streamgate -run '^Test(CommitBoundary|StreamReleaser)'`
   - 기대 결과: PASS.
4. `go test -count=1 ./packages/go/streamgate`
   - 기대 결과: PASS.
5. `go test -race -count=1 ./packages/go/streamgate`
   - 기대 결과: PASS, race 없음.
6. `go vet ./packages/go/streamgate`
   - 기대 결과: PASS, stdout 없음.
7. `make proto`
   - 기대 결과: 성공, proto 생성물 추가 diff 없음.
8. `go test -count=1 ./apps/edge/internal/transport ./apps/node/internal/transport`
   - 기대 결과: PASS. 동일 host GOROOT setup failure면 우회 없이 원문/exit code/host Go 복구 조건을 기록.
9. `git diff --check -- packages/go/streamgate/commit_boundary.go packages/go/streamgate/commit_boundary_test.go packages/go/streamgate/stream_release.go packages/go/streamgate/stream_release_test.go agent-task/m-stream-evidence-gate-core/07+01,06_commit_boundary proto/gen/iop`
   - 기대 결과: stdout 없음.
10. `git status --short -- proto/gen/iop`
    - 기대 결과: stdout 없음.

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다.
