<!-- task=m-stream-evidence-gate-core/19+18_core_runtime_loop plan=9 tag=REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_CORE_RUNTIME_LOOP -->

# Plan - Stream Gate core runtime 계약과 lifecycle evidence closure

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

구현·테스트·실제 검증 evidence만 소유한다. 아래 체크리스트를 끝낸 뒤 active `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 stdout/stderr로 채우고 active pair를 그대로 둔 채 리뷰 준비 완료를 보고한다. 차단 시 정확한 blocker, 시도한 명령/출력, 재개 조건만 구현 소유 evidence에 기록한다. 사용자에게 결정을 묻거나 user-input 도구·control-plane stop 파일을 만들거나 다음 상태를 분류하지 않으며, log archive·`complete.log`·roadmap·`WORK_LOG.md`는 수정하지 않는다.

## 배경

직전 구현은 production package build는 되지만 runtime test가 타입·중복 선언 오류로 컴파일되지 않아 기록된 PASS evidence를 재현할 수 없다. same-ID continuation, dispatched binding의 abort 실패, terminal timestamp와 fatal cause identity도 SDD 계약을 위반하며, lifecycle 테스트 대부분은 요구된 exact order/count를 검증하지 않는다. 이 후속은 남은 production 결함과 검증 fixture를 함께 닫아 실제 fresh unit/race 결과로 완료 여부를 판정할 수 있게 한다.

## Archive Evidence Snapshot

- 이전 Plan: `agent-task/m-stream-evidence-gate-core/19+18_core_runtime_loop/plan_local_G08_8.log`
- 이전 Review: `agent-task/m-stream-evidence-gate-core/19+18_core_runtime_loop/code_review_cloud_G08_8.log`
- 판정: `FAIL`
- 문제 수: Required 5, Suggested 0, Nit 0
- 문제 요약:
  - `runtime_test.go`의 미정의 타입, 잘못된 정수 타입, 중복 선언 때문에 모든 Go test가 compile failure이며 기록된 PASS 출력이 checkout과 일치하지 않는다.
  - `ContinueOpenAttempt`이 같은 old/new attempt ID를 허용해 identity 전이 없이 generation만 증가시킨다.
  - recovery install prepare 실패에서 새 controller abort 오류를 버려 `attempt_abort_failed`와 no-live-attempt 증거가 없다.
  - success terminal timestamp를 `time.Now()`로 덮고 fatal cause의 consumer/filter/rule 필드를 잘못 매핑한다.
  - continuation/install failure/lifecycle/releaser 테스트가 assertion 없는 skeleton 또는 일부 happy path라 SDD의 cap·failure·cancel·snapshot·exact order/count matrix를 증명하지 못한다.
- 영향 파일: `packages/go/streamgate/commit_boundary.go`, `commit_boundary_test.go`, `runtime.go`, `runtime_test.go`, `stream_release_test.go`.
- 실제 검증 evidence:
  - `/config/.local/bin/go` → `/config/opt/go/bin/go`, Go `1.26.2`; `go build ./packages/go/streamgate`, `make proto`, gofmt, import/debug guard, `git diff --check`는 통과했다.
  - `go test -count=1 -v ./packages/go/streamgate -run '^TestRequestRuntimeLifecycleMatrix$'`는 `runtime_test.go:1152:77: undefined: Fingerprint`, `:1153`의 `uint64`→`int` 불일치 2건, `:1333:8: no new variables on left side of :=`로 build failure다.
  - test compile failure 때문에 focused/package/race PASS 주장은 재현되지 않았으며 다시 실행해야 한다.
- 필요한 경우 위 두 archive log만 좁게 읽는다. `agent-task/archive/**`를 탐색하지 않는다.
- Roadmap carryover: 없음. 이 split subtask PASS만으로 Milestone 기능 Task 완료를 주장하지 않으므로 `Roadmap Targets`를 두지 않는다.

## 분석 결과

### 읽은 파일

- 규칙/현재 지점: `agent-ops/rules/project/rules.md`, `agent-ops/rules/common/rules-roadmap.md`, `agent-roadmap/current.md`.
- skill/domain/test 규칙: `agent-ops/skills/common/router.md`, `agent-ops/skills/common/code-review/SKILL.md`, `agent-ops/skills/common/plan/SKILL.md`, `agent-ops/skills/common/finalize-task-routing/SKILL.md`, `agent-ops/rules/project/domain/platform-common/rules.md`, `agent-ops/rules/project/domain/testing/rules.md`, `agent-test/local/rules.md`, `agent-test/local/platform-common-smoke.md`, `agent-test/local/testing-smoke.md`.
- spec/contract routing: `agent-ops/rules/common/rules-agent-spec.md`, `agent-spec/index.md`, `agent-contract/index.md`; 이 intra-package runtime에 매칭되는 active spec/contract는 없다.
- roadmap/SDD: `agent-roadmap/phase/knowledge-tool-optimization-extension/PHASE.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/18+14,16_runtime_contract/complete.log`.
- production source: `packages/go/streamgate/commit_boundary.go`, `stream_release.go`, `recovery_coordinator.go`, `runtime.go`; 관련 정의는 `event.go`, `terminal.go`, `decision_arbiter.go`의 terminal/cause 경로를 대조했다.
- tests: `packages/go/streamgate/commit_boundary_test.go`, `stream_release_test.go`, `recovery_coordinator_test.go`, `runtime_test.go`, `runtime_contract_test.go`.
- prior loop evidence: 위 `Archive Evidence Snapshot`의 정확한 두 archive log.

### SDD 기준

- SDD: `agent-roadmap/sdd/knowledge-tool-optimization-extension/stream-evidence-gate-core/SDD.md`, 상태 `승인됨`, 구현 잠금 해제.
- 직접 관련 Milestone Task ids: `[recovery-coordinator]`, `[vertical-slice]`; `[commit-boundary]`, `[parallel-evaluation]`, `[decision-arbiter]`, `[event-contract]`은 회귀 불변조건이다.
- Acceptance/Evidence Map: S03/S05의 stream-open/단일 terminal, S12/S13의 blocking·observe-only failure와 deterministic action, S14의 simultaneous intent·0/1/3 cap·cancel, S16의 vertical cycle, S18의 prefix/look-behind/cursor 및 duplicate opening 억제, S20의 no-overlap attempt, S21의 bounded sanitized cause/terminal once, S23의 abort→prepare→snapshot release→rebuild→dispatch 순서다.
- 위 행을 구현 항목 1~3의 identity/terminal/fixture assertion과 final focused/race 명령에 직접 반영한다.

### 테스트 환경 규칙

- `test_env=local`.
- `agent-test/local/rules.md`, `agent-test/local/platform-common-smoke.md`, `agent-test/local/testing-smoke.md`를 읽었고 blank/skeleton 또는 `<확인 필요>` 값은 없다.
- `/config/.local/bin/go`가 `/config/opt/go/bin/go`로 해석되는지 확인하고 `make proto` 뒤 모든 Go test를 `-count=1`로 fresh 실행한다. focused/package `-race`, `go build`, `gofmt -d`, debug/ignored-error guard, import boundary, `git diff --check`를 적용한다. cached Go test 출력은 허용하지 않는다.
- 검증은 현재 checkout 안에서 끝나므로 non-local preflight는 해당 없다. repo 안에 임시 fixture/tool을 남기지 않는다.

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

- `commit_boundary_test.go`: same-ID, active reservation, confirmed output/start count 보존을 함께 검증하지 않는다.
- `runtime_test.go`: 현재 compile failure이며 continuation은 goroutine 오류를 버리고 sleep 뒤 boundary ID/state만 본다.
- `TestRequestRuntimeAtomicInstallFailure`는 assertion이 없고 dispatched controller를 사용하지 않으며, recovery failure order도 결과를 assertion하지 않는다.
- `TestRequestRuntimeTerminalFailureFidelity`는 descriptor code만 보고 success timestamp, provider cause chain, fatal consumer/filter/rule, cause cap을 보지 않는다.
- lifecycle matrix는 simultaneous violation 단일 subtest의 terminal count만 보며 0/1/3 cap, enforcement error, backpressure/cancel, component failures, snapshot release, exact trace가 없다.
- `TestStreamReleaserPassThroughAndTerminal`은 response-start/release/terminal failure와 serializer conflict를 포함하지 않는다.

### 심볼 참조

- rename/remove 대상은 없다.
- `ContinueOpenAttempt`, `RequestRuntime.prepareAttemptInstall`, `commitAttemptInstall`, terminal conversion helper의 기존 package-local call site만 수정하며 외부 API call site는 추가하지 않는다.

### 분할 판단

- split policy를 재평가했다. boundary identity, runtime attempt ownership, terminalization, lifecycle fixture는 같은 owner loop의 상태와 exact trace를 공유하므로 독립 완료 가능한 경계가 아니다.
- 별도 plan으로 나누면 compile-fix만 먼저 통과하거나 production correction 없이 약한 테스트를 고정할 위험이 있어 단일 plan에서 계약과 evidence를 함께 수렴한다.
- subtask `19+18_core_runtime_loop`의 predecessor `18`은 `agent-task/archive/2026/07/m-stream-evidence-gate-core/18+14,16_runtime_contract/complete.log`의 PASS로 충족됐다.

### 범위 결정 근거

- production 변경은 `commit_boundary.go`, `runtime.go`로 한정하고 직접 regression은 `commit_boundary_test.go`, `runtime_test.go`, `stream_release_test.go`에 둔다.
- `stream_release.go`, `recovery_coordinator.go`, `recovery_coordinator_test.go`, `runtime_contract_test.go`, `event.go`, `terminal.go`, `decision_arbiter.go`, `evidence_tail.go`는 현재 계약 기준선이며 새 결함 증거가 없으면 수정하지 않는다.
- Edge/Node/OpenAI adapter, config/proto schema, observability, roadmap/SDD/spec/contract 문서는 변경하지 않는다. `agent-task/m-stream-evidence-gate-core/WORK_LOG.md`는 dispatcher 소유이므로 수정하지 않는다.

### 최종 라우팅

- evaluation mode: `isolated-reassessment`; finalizer: `finalize-task-policy.sh`; finalizer mode: `pair`; status: `routed`.
- build closures: scope/context/verification/evidence/ownership/decision 모두 `true`.
  - scope: 5개 Required의 source path, 계약 위반, assertion 목표가 확정됐다.
  - context: production/test/SDD와 재현 실패를 함께 읽었고 관련 package 밖 영향은 없다.
  - verification: fresh focused/package/race와 exact trace/count로 성공 판정이 가능하다.
  - evidence: 기존 PASS 기록은 불신하지만 compile failure와 정적 결함은 현재 checkout에서 재현·대조돼 신뢰 가능하다.
  - ownership: package와 active split task 소유권이 명확하며 dispatcher의 `WORK_LOG.md`는 제외한다.
  - decision: 승인된 SDD로 의미가 닫혀 사용자 결정·외부 권한이 필요 없다.
- build route basis: `grade-boundary`; capability gap: `none`; scores scope coupling 2, state concurrency 2, blast irreversibility 1, evidence diagnosis 2, verification complexity 2 = `G09`; lane `cloud`; filename `PLAN-cloud-G09.md`; grade floor `none`.
- build loop risk: `temporal_state`, `concurrent_consistency`, `boundary_contract`, `variant_product` matched, `triggered=true`; structured interpretation은 없다.
  - ordered transitions: uncommitted→stream-open→recovery→handoff/replace→terminal과 duplicate/cancel/failure 경로.
  - concurrent consistency: event owner, gate worker, controller, sink의 atomic handoff/exactly-once/race-free 제약.
  - boundary contract: boundary/releaser/runtime/coordinator와 sink/controller consumer의 identity·serializer·immutability 제약.
  - variant product: resume mode, enforcement, cap, failure stage의 독립 축과 조합 검증.
- review closures: scope/context/verification/evidence/ownership/decision 모두 `true`; 동일한 source/diff/fresh command를 독립 대조할 수 있다.
- review route basis: `official-review`; capability gap: `none`; scores 2/2/1/2/2 = `G09`; lane `cloud`; filename `CODE_REVIEW-cloud-G09.md`; Codex `gpt-5.6-sol` xhigh; grade floor `none`.

## 구현 체크리스트

- [ ] boundary continuation이 empty/same/wrong ID와 reservation/state 경계를 거부하고 정상 handoff에서 start·confirmed output·state를 보존하도록 고치며 regression을 통과시킨다.
- [ ] runtime의 dispatched binding abort 결과, install failure cause/order, success terminal timestamp, fatal consumer/filter/rule mapping을 계약대로 고치고 regression을 통과시킨다.
- [ ] runtime/releaser fixture를 compile-clean deterministic recorder/table로 완성해 passthrough·continuation·0/1/3 cap·failure·cancel·snapshot·exact count/order를 검증한다.
- [ ] environment/proto/focused/package/race/format/guard/import/diff 명령을 fresh 실행하고 실제 stdout/stderr를 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다.

### [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_CORE_RUNTIME_LOOP-1] continuation identity와 boundary 보존 계약

#### 문제

- `packages/go/streamgate/commit_boundary.go:505`는 새 ID의 empty만 거부해 `ContinueOpenAttempt("a1", "a1")`이 성공하고 generation을 증가시킨다.
- `packages/go/streamgate/commit_boundary_test.go:1307`은 same-ID/reservation과 response-start·confirmed output 보존을 assertion하지 않는다.

#### 해결 방법

Before (`packages/go/streamgate/commit_boundary.go:505`):

```go
func (b *CommitBoundary) ContinueOpenAttempt(oldAttemptID, newAttemptID string) error {
    if newAttemptID == "" {
        return errors.New("streamgate: continue open attempt new id is required")
    }
    // ... stream_open과 old ID 확인 뒤 attemptID/generation 변경
}
```

After:

```go
func (b *CommitBoundary) ContinueOpenAttempt(oldAttemptID, newAttemptID string) error {
    // empty old/new와 old == new를 identity 오류로 거부한다.
    // serializer idle, stream_open, exact current old ID를 확인한 뒤에만 ID와 generation을 변경한다.
    // staged/confirmed output과 commit state는 변경하지 않는다.
}
```

#### 수정 파일 및 체크리스트

- [ ] `packages/go/streamgate/commit_boundary.go`: same-ID를 side effect 전에 거부하고 기존 serializer/state/attempt typed error를 유지한다.
- [ ] `packages/go/streamgate/commit_boundary_test.go`: empty/same/wrong, reservation, uncommitted/terminal, 정상 handoff의 generation·start count·confirmed output·old/new operation matrix를 추가한다.

#### 테스트 작성

- 작성: `TestCommitBoundaryContinuesOpenAttempt`를 table/subtest로 확장한다. 같은 ID 실패 전후 generation 불변, 정상 handoff에서 prefix가 재방출되지 않음, old ID 거부/new ID release·terminal 성공을 assertion한다.

#### 중간 검증

- `go test -count=1 -v ./packages/go/streamgate -run '^TestCommitBoundaryContinuesOpenAttempt$'`
- 기대 결과: 모든 identity/state/reservation subtest PASS, sink exact count와 boundary 보존 assertion 일치.

### [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_CORE_RUNTIME_LOOP-2] recovery abort closure와 terminal fidelity

#### 문제

- `packages/go/streamgate/runtime.go:906`의 prepare 실패는 `AbortAttempt` 오류를 무시하고 terminal cause에 반영하지 않는다.
- `packages/go/streamgate/runtime.go:976`은 success terminal event timestamp 대신 `time.Now()`를 사용하고, `:1008`은 filter/rule을 consumer/filter 위치에 넣는다.
- `packages/go/streamgate/runtime_test.go:1200`, `:1259`, `:1295`는 이 경로의 identity, abort count, cause chain, side-effect order를 증명하지 않는다.

#### 해결 방법

Before (`packages/go/streamgate/runtime.go:906`, `:976`, `:1008`):

```go
if prepErr != nil {
    if newCtrl := newBinding.Controller(); newCtrl != nil {
        _ = newCtrl.AbortAttempt(ctx)
    }
}
termRes, errRes := NewSuccessTerminalResult(ev.Channel(), time.Now())
cause, errC := NewFailureCause("arbiter", "fatal_violation", arbResult.FilterID(), arbResult.RuleID(), "")
```

After:

```go
// prepare/commit 실패 모두 새 controller abort 결과를 수집한다.
// install_*_failed 뒤 abort 실패가 있으면 attempt_abort_failed를 append하고 pending discard 후 terminal을 한 번 commit한다.
termRes, errRes := ev.AsTerminal()
cause, errC := NewFailureCause("arbiter", "fatal_violation", "", arbResult.FilterID(), arbResult.RuleID())
```

모든 terminal/cause constructor 오류를 반환하고 raw provider/controller 오류 문자열은 외부 descriptor나 sanitized cause에 넣지 않는다. abort→discard→terminal 순서를 recorder로 고정하고 old/new controller live state와 호출 횟수를 assertion한다.

#### 수정 파일 및 체크리스트

- [ ] `packages/go/streamgate/runtime.go`: prepare/commit 공통 abort-cause 생성과 terminalization을 오류 손실 없이 수렴한다.
- [ ] `packages/go/streamgate/runtime.go`: success `AsTerminal()`과 fatal consumer/filter/rule 매핑을 적용한다.
- [ ] `packages/go/streamgate/runtime_test.go`: abort success/failure, prepare/commit failure, success/provider/fatal terminal timestamp·descriptor·cause·cap regression을 작성한다.

#### 테스트 작성

- 작성: `TestRequestRuntimeAtomicInstallFailure`는 유효한 dispatched binding 뒤 local prepare/commit 실패를 만들고 new abort 1회, old abort 중복 없음, abort→discard→terminal, 단일 terminal, `attempt_abort_failed` 조건부 cause를 assertion한다.
- 작성: `TestRequestRuntimeRecoveryFailureOrder`는 sleep/goroutine 오류 무시를 제거하고 channel/recorder barrier로 run 종료와 exact trace를 기다린다.
- 작성: `TestRequestRuntimeTerminalFailureFidelity`는 success event timestamp, provider descriptor/cause identity, fatal empty consumer+정확한 filter/rule, raw-free·최대 4 cause를 assertion한다.

#### 중간 검증

- `go test -count=1 -v ./packages/go/streamgate -run '^(TestRequestRuntimeTerminalFailureFidelity|TestRequestRuntimeAtomicInstallFailure|TestRequestRuntimeRecoveryFailureOrder)$'`
- 기대 결과: 모든 terminal/install subtest PASS, exact abort/cause/order/count 일치.

### [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_CORE_RUNTIME_LOOP-3] compile-clean deterministic lifecycle matrix

#### 문제

- `packages/go/streamgate/runtime_test.go:1152`, `:1153`, `:1333`의 타입·중복 선언 오류로 package tests가 컴파일되지 않는다.
- `TestRequestRuntimeContinuationLifecycle`, `TestRequestRuntimeLifecycleMatrix`, `TestStreamReleaserPassThroughAndTerminal`이 계획된 상태/실패 조합과 exact trace를 검증하지 않는다.

#### 해결 방법

Before (`packages/go/streamgate/runtime_test.go:1152`, `:1295`, `:1323`):

```go
func mustSanitizedEvidence(... fp Fingerprint, seq, offset uint64, ...) SanitizedEvidence
go func() { _ = rt.Run(ctx) }()
time.Sleep(20 * time.Millisecond)
func TestRequestRuntimeLifecycleMatrix(t *testing.T) { /* one terminal-count subtest */ }
```

After:

```go
func mustSanitizedEvidence(... fp FixedFingerprint, seq, offset int, ...) SanitizedEvidence
// thread-safe recorder와 explicit barrier로 event/abort/snapshot/rebuild/dispatch/sink 순서를 기다린다.
// 각 table row는 Run 결과, terminal count, attempt count, snapshot release count와 full trace를 비교한다.
```

fixture가 production 내부 상태를 대신 계산하지 않게 실제 `RequestRuntime.Run`과 boundary/releaser sink를 통과시킨다. 독립 축 전체를 무작정 곱하지 않고 SDD가 요구한 대표 조합을 명시하되 각 row의 입력과 기대 trace를 고정한다.

#### 수정 파일 및 체크리스트

- [ ] `packages/go/streamgate/runtime_test.go`: helper 타입/중복 선언을 고치고 sleep 기반 fixture를 deterministic barrier/recorder로 교체한다.
- [ ] `packages/go/streamgate/runtime_test.go`: no-filter/all-disabled/observe-only/blocking 비구독 event, initial/replace/continue opening과 prefix/cursor/look-behind 보존을 assertion한다.
- [ ] `packages/go/streamgate/runtime_test.go`: simultaneous winner, 0/1/3 cap, blocking/observe-only error, backpressure/cancel, controller/preparer/rebuilder/dispatcher/sink failure, snapshot release의 exact trace/count table을 완성한다.
- [ ] `packages/go/streamgate/stream_release_test.go`: passthrough start/release/terminal success와 각 sink failure, serializer conflict, terminal reentry를 table로 완성한다.

#### 테스트 작성

- 작성: `TestRequestRuntimePassThroughMatrix`, `TestRequestRuntimeContinuationLifecycle`, `TestRequestRuntimeLifecycleMatrix`를 위 fixture로 강화한다.
- 작성: `TestStreamReleaserPassThroughAndTerminal`에 response-start/release/terminal error와 concurrent serializer conflict subtest를 추가한다.
- skip 없음: 모두 직전 FAIL의 behavior/regression이며 fresh `-race`까지 필수다.

#### 중간 검증

- `go test -count=1 -v ./packages/go/streamgate -run '^(TestStreamReleaserPassThroughAndTerminal|TestRequestRuntimePassThroughMatrix|TestRequestRuntimeContinuationLifecycle|TestRequestRuntimeLifecycleMatrix)$'`
- 기대 결과: 모든 table row PASS, sleep 없는 deterministic full trace와 exact side-effect count 일치.

## 의존 관계 및 구현 순서

1. item 1의 boundary identity를 먼저 고정한다.
2. item 2에서 runtime이 고정된 handoff/terminal 계약을 소비하게 한다.
3. item 3의 fixture로 전체 조합과 race를 닫는다.
4. predecessor `18`은 위 archived `complete.log`로 이미 충족됐으며 추가 sibling 대기는 없다.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `packages/go/streamgate/commit_boundary.go` | 1 |
| `packages/go/streamgate/commit_boundary_test.go` | 1 |
| `packages/go/streamgate/runtime.go` | 2 |
| `packages/go/streamgate/runtime_test.go` | 2, 3 |
| `packages/go/streamgate/stream_release_test.go` | 3 |

## 최종 검증

- Environment: `command -v go && readlink -f "$(command -v go)" && go version && go env GOROOT`
- Proto: `make proto`
- Build: `go build ./packages/go/streamgate`
- Formatting: `gofmt -d packages/go/streamgate/commit_boundary.go packages/go/streamgate/commit_boundary_test.go packages/go/streamgate/runtime.go packages/go/streamgate/runtime_test.go packages/go/streamgate/stream_release_test.go`
- Focused behavior: `go test -count=1 -v ./packages/go/streamgate -run '^(TestCommitBoundaryContinuesOpenAttempt|TestStreamReleaserPassThroughAndTerminal|TestRequestRuntimePassThroughMatrix|TestRequestRuntimeContinuationLifecycle|TestRequestRuntimeTerminalFailureFidelity|TestRequestRuntimeAtomicInstallFailure|TestRequestRuntimeRecoveryFailureOrder|TestRequestRuntimeLifecycleMatrix)$'`
- Snapshot contract: `go test -count=1 -v ./packages/go/streamgate -run '^TestRequestRuntimeSnapshotContract'`
- Focused race: `go test -race -count=1 ./packages/go/streamgate -run '^(TestCommitBoundaryContinuesOpenAttempt|TestStreamReleaserPassThroughAndTerminal|TestRequestRuntime)'`
- Package unit: `go test -count=1 ./packages/go/streamgate`
- Package race: `go test -race -count=1 ./packages/go/streamgate`
- Ignored-error/debug guard: `! rg -n --sort path 'DEBUG|, _ := New|_ = New|desc, _ :=|cause, _ :=|causes, _ :=' packages/go/streamgate/runtime.go packages/go/streamgate/runtime_test.go`
- Import boundary: `! rg -n --sort path 'iop/apps/' packages/go/streamgate/commit_boundary.go packages/go/streamgate/runtime.go packages/go/streamgate/commit_boundary_test.go packages/go/streamgate/runtime_test.go packages/go/streamgate/stream_release_test.go`
- Diff: `git diff --check`
- 기대 결과: 모든 명령 exit 0, gofmt/guard/import/diff 출력 없음, 모든 test fresh PASS. cached Go test 출력은 허용하지 않는다.

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