<!-- task=m-stream-evidence-gate-core/06+01_evidence_tail plan=5 tag=REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API -->

# Stream Gate fragment sequence 정리와 public evidence 신뢰 복구 계획

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

구현과 검증을 완료한 항목만 체크하고, 마지막에 active `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 변경 내용과 명령 출력으로 채운다. active pair는 그대로 두고 리뷰 준비 완료만 보고한다. 최종 판정, log rename, `complete.log`, task archive와 다음 상태 분류는 코드리뷰 에이전트 책임이다. 구현이 막히면 정확한 blocker, 실행한 명령/출력, 재개 조건만 구현 소유 evidence에 기록하며 사용자 질문, user-input tool, control-plane stop 파일, archive 작업은 수행하지 않는다.

## 배경

fragment entry는 absolute monotonic sequence를 저장하지만 confirm 정리 경로가 이를 slice-relative count로 변환해 두 번째 sequential fragment부터 완료 상태를 남긴다. 현재 reprepare/fragment/Korean 회귀도 여러 public API 오류를 버리고 동일한 payload의 길이만 확인해 잘못된 suffix/order를 green으로 만들 수 있다. absolute sequence 정리와 오류를 숨기지 않는 exact-content 회귀를 같은 lifecycle write-set에서 폐쇄한다.

## Archive Evidence Snapshot

- 이전 plan: `agent-task/m-stream-evidence-gate-core/06+01_evidence_tail/plan_local_G06_4.log`
- 이전 review: `agent-task/m-stream-evidence-gate-core/06+01_evidence_tail/code_review_local_G07_4.log`
- 판정: `FAIL`
- Required:
  - `ConfirmRelease`가 absolute fragment sequence를 `n`과 비교하고 `seq-n`으로 저장해 non-zero sequence의 full confirm 뒤 완료된 fragment state를 남긴다.
  - reprepare/fragment/Korean 필수 public regression이 constructor, `Append`, `PrepareRelease`, `ConfirmRelease`, `CompleteFragment`, content accessor 오류를 버리고 exact suffix/order를 충분히 검증하지 않는다.
- Suggested: 없음
- Nit: 없음
- 영향 파일: `packages/go/streamgate/evidence_tail.go`, `packages/go/streamgate/evidence_tail_test.go`, active review stub.
- 현재 검증 evidence:
  - fresh focused/full/race/vet/gofmt/diff/proto hygiene는 PASS했다.
  - 리뷰 집중 재현은 첫 fragment cycle 뒤 다음 unique fragment를 full confirm했을 때 `fragmentState`가 `got 1, want 0`으로 실패했다.
  - required test 구간에 `ev, _ :=`, unchecked `Append`/`PrepareRelease`/`ConfirmRelease`/`CompleteFragment`, unchecked content accessor가 남아 있다.
  - local transport unit은 host GOROOT의 `crypto/internal/fips140cache` 누락으로 setup failure다.
- Roadmap carryover: 이 subtask는 S01/S02 evidence-tail state와 S19 tail-side fail-closed signal만 준비한다. attempt cancel→terminal/no-release 통합과 `evidence-tail` Roadmap Task 완료는 dependent `07+01,06_commit_boundary`가 소유하므로 `Roadmap Targets`를 두지 않는다.
- 구현자는 위 두 task log와 선행 완료 근거 `agent-task/archive/2026/07/m-stream-evidence-gate-core/01_event_contract_types/complete.log` 외의 `agent-task/archive/**`를 탐색하지 않는다.

## 분석 결과

### 읽은 파일

- `AGENTS.md`
- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-ops/rules/common/rules-agent-spec.md`
- `agent-ops/rules/project/domain/platform-common/rules.md`
- `agent-ops/rules/project/domain/testing/rules.md`
- `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/skills/common/plan/templates/review-stub-template.md`
- `agent-test/local/rules.md`
- `agent-test/local/platform-common-smoke.md`
- `agent-roadmap/current.md`
- `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-spec/index.md`
- `agent-contract/index.md`
- `agent-task/m-stream-evidence-gate-core/06+01_evidence_tail/plan_local_G06_4.log`
- `agent-task/m-stream-evidence-gate-core/06+01_evidence_tail/code_review_local_G07_4.log`
- `agent-task/archive/2026/07/m-stream-evidence-gate-core/01_event_contract_types/complete.log`
- `packages/go/streamgate/evidence_tail.go`
- `packages/go/streamgate/evidence_tail_test.go`
- `packages/go/streamgate/event.go`의 `NormalizedEvent`/`ReleaseEvent` constructor와 accessor 구간
- `packages/go/streamgate/filter_contract.go`의 `cloneNormalizedEvent` 구간

`agent-spec/index.md`와 `agent-contract/index.md`에는 내부 evidence-tail release lifecycle에 매칭되는 별도 living spec/contract 문서가 없다. 코드, 승인 SDD와 공개 API 테스트를 직접 기준으로 삼는다.

### SDD 기준

- 문서: `agent-roadmap/sdd/knowledge-tool-optimization-extension/stream-evidence-gate-core/SDD.md`
- 상태: `[승인됨]`, SDD 잠금 `해제`, 사용자 결정 항목 없음.
- S01 / `evidence-tail`: pending/look-behind가 bounded하고 partial/full confirm 뒤 exact release capability와 state 정리가 유지돼야 한다.
- S02 / `evidence-tail`: Korean multi-byte input과 trailing suffix를 Unicode rune boundary로 보존해야 한다.
- S19 / `evidence-tail`: hard overflow는 no partial release fail-closed signal이어야 하며 attempt cancel/terminal 통합은 dependent commit-boundary subtask 책임이다.
- Evidence Map의 S01/S02가 absolute fragment sequence cleanup, distinct reprepare/fragment order, 2/200/500 exact Korean suffix 회귀를 결정했다. S19는 기존 overflow signal 회귀를 유지하고 sibling 소유의 attempt cancellation을 이 write-set에 넣지 않는 경계다.

### 테스트 환경 규칙

- `test_env`: `local`
- `agent-test/local/rules.md`: 존재하며 전체를 읽었다. PATH에서 해석되는 host Go를 고정하고 별도 toolchain 우회를 금지한다.
- 매칭 profile: `agent-test/local/platform-common-smoke.md`
- host: `/config/.local/bin/go` → `/config/opt/go/bin/go`, `go1.26.2 linux/arm64`, `GOROOT=/config/opt/go`.
- 적용 검증: fresh focused/full package test, race, vet, gofmt, diff hygiene, proto generated tree status, required regression의 ignored-error search와 transport unit 실행.
- proto/config/wire source는 바꾸지 않으므로 `make proto`는 실행하지 않고 `git status --short -- proto/gen/iop`로 생성물 비변경만 확인한다.
- transport profile의 실제 package는 `./apps/edge/internal/transport`와 `./apps/node/internal/transport`다. 현재 host GOROOT의 `crypto/internal/fips140cache` 누락으로 setup failure이며, host Go 설치 복구가 재개 조건이다. 이 blocker는 `./packages/go/streamgate`의 결정적 focused/full/race 검증을 대체하지 않는다.
- cached test output은 허용하지 않으며 모든 Go test에 `-count=1`을 사용한다.

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

- 현재 fragment A/B 회귀는 sequence 0에서 시작한 한 흐름만 확인해 non-zero absolute sequence의 다음 full confirm 뒤 완료 state 누적을 검출하지 못한다.
- reprepare 회귀는 모든 event가 같은 `aaaaaaaaaa` payload여서 실제 suffix가 아닌 다른 두 event를 반환해도 통과할 수 있다.
- fragment 회귀는 `[B1,A2]`의 길이만 확인하고 public release content와 order를 확인하지 않는다.
- Korean table은 반복 `'가'`와 길이만 확인해 실제 trailing 2/200/500-rune content 선택을 증명하지 못한다.
- 위 세 required 회귀에 unchecked constructor/lifecycle/content accessor 호출이 남아 setup 실패를 zero value로 숨길 수 있다.

### 심볼 참조

- 공개 signature 변경은 없다.
- 관련 public API 직접 call site는 `packages/go/streamgate/evidence_tail_test.go`뿐이며 production caller는 아직 없다.
- 내부 변경 대상은 `ConfirmRelease`의 `fragmentState.entries`, `targetEpoch.snapStartSeq`와 confirmation range 계산이다.

### 분할 판단

split decision policy를 재평가했다. Production defect와 regression 신뢰 복구는 같은 `ConfirmRelease` fragment lifecycle을 판정하는 최소 bug-fix unit이며 두 파일만 공유한다. Production/test 분리는 첫 child의 PASS evidence를 불완전하게 만들고 동일 write-set 경쟁을 만들므로 기존 `06+01_evidence_tail` 단일 plan을 유지한다. 디렉터리의 `+01` 선행 의존은 `agent-task/archive/2026/07/m-stream-evidence-gate-core/01_event_contract_types/complete.log`로 충족됐다.

### 범위 결정 근거

- write-set은 `packages/go/streamgate/evidence_tail.go`, `packages/go/streamgate/evidence_tail_test.go`, 이 task directory의 active implementation evidence로 제한한다.
- `ReleaseSink`, `CommitBoundary`, registry/policy, transport, proto/config, roadmap/SDD/spec/contract, sibling task와 dispatcher-owned `WORK_LOG.md`는 수정하지 않는다.
- public signature와 token format은 바꾸지 않는다.
- unrelated dirty worktree와 동시에 실행 중인 공식 review 산출물은 읽기/수정 대상에서 제외한다.

### 최종 라우팅

- evaluation mode: `isolated-reassessment`
- 격리 입력: absolute fragment sequence failure, required public regression의 unchecked errors/exact-content 공백, 두 source/test 파일, 승인 SDD S01/S02/S19, local 검증과 sibling ownership만 sealed neutral scratch snapshot에 포함했다. 이전 route-bearing 값과 archive basename은 평가 입력에서 제외했다.
- build closures: scope/context/verification/evidence/ownership/decision 모두 `true`. 두 Required는 한 state machine과 두 파일 안에서 결정적 test로 구현·검증 가능하다.
- build scores: scope coupling `1`, state/concurrency `2`, blast/irreversibility `1`, evidence diagnosis `1`, verification complexity `1`.
- build formatter output: lane `local`, grade `G06`, filename `PLAN-local-G06.md`.
- review closures: scope/context/verification/evidence/ownership/decision 모두 `true`. green suite와 failing sequence reproducer 및 ignored-error evidence를 함께 재검증할 수 있다.
- review scores: scope coupling `1`, state/concurrency `2`, blast/irreversibility `1`, evidence diagnosis `2`, verification complexity `1`.
- review formatter output: lane `local`, grade `G07`, filename `CODE_REVIEW-local-G07.md`.

## 구현 체크리스트

- [ ] `REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-1` confirmed absolute sequence range만 fragment state에서 제거하고 non-zero sequence의 sequential/partial/full confirm 뒤 완료 state가 남지 않게 한다.
- [ ] `REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-2` reprepare/fragment/Korean required 회귀의 모든 public API 오류를 검사하고 distinct payload의 exact suffix/content/order와 bounded fragment cleanup을 고정한다.
- [ ] fresh focused/full/race/vet, gofmt/diff/proto/ignored-error hygiene와 host transport setup 결과를 실제 출력으로 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다.

### [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-1] Absolute fragment sequence 정리

**문제**

- `packages/go/streamgate/evidence_tail.go:1618-1630`은 `fragmentState.entries`의 monotonic absolute sequence를 confirmation event count `n`과 비교하고 `seq-n`으로 바꾼다.
- sequence 0 fragment는 우연히 제거되지만 다음 sequential fragment는 sequence 1을 `n=1` confirm한 뒤 `0`으로 남아 request-local fragment state가 누적된다.

**해결 방법**

```go
// Before: absolute sequence를 slice-relative count처럼 취급한다.
for _, seq := range fragment.entries {
	if seq >= n {
		remaining = append(remaining, seq-n)
	}
}
```

```go
// After: 현재 epoch의 confirmed absolute range만 제거한다.
confirmedEndSeq := targetEpoch.snapStartSeq + n
for _, seq := range fragment.entries {
	if seq >= confirmedEndSeq {
		remaining = append(remaining, seq)
	}
}
```

- `targetEpoch.snapStartSeq`를 전진시키기 전에 confirmed end를 계산한다.
- 아직 confirm되지 않은 fragment entry의 absolute sequence는 변경하지 않는다.
- 완료 fragment의 모든 entry가 confirmed되면 map entry를 삭제하고 incomplete suffix state는 보존한다.
- reprepare start advancement와 channel-scoped invalidation 동작은 유지한다.

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

- [ ] `packages/go/streamgate/evidence_tail.go`: absolute confirmed range 기준 fragment state cleanup
- [ ] `packages/go/streamgate/evidence_tail_test.go`: non-zero sequence sequential/partial/full confirm 뒤 fragment state bounded cleanup 회귀

**테스트 작성**

- `TestEvidenceTailFragmentCompletionPreservesOtherChannels`에 distinct tool-call ID를 순차 append→complete→prepare→confirm하는 subtest를 추가한다.
- 첫 cycle 뒤 시작 sequence가 0이 아닌 두 번째/세 번째 cycle에서도 public release content가 정확하고 confirm 뒤 해당 fragment state가 제거되며 pending/cursor가 일치하는지 확인한다.

**중간 검증**

```bash
/config/.local/bin/go test -count=1 ./packages/go/streamgate -run '^(TestEvidenceTailFragmentCompletionPreservesOtherChannels|TestEvidenceTailFragmentCompletionCreatesSafePrefixEpoch)$'
```

기대 결과: non-zero absolute sequence fragment cleanup과 기존 channel 격리 회귀 전체 PASS, cached output 없음.

### [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-2] Public regression evidence 신뢰 복구

**문제**

- `packages/go/streamgate/evidence_tail_test.go:2604-2740`, `3547-3674`, `4006-4046`에 constructor, `Append`, `PrepareRelease`, `ConfirmRelease`, `CompleteFragment`, `AsTextDelta` 오류를 버리는 호출이 남아 있다.
- 동일 payload와 length-only assertion은 reprepare suffix, fragment `[B1,A2]` order, Korean trailing suffix 선택을 증명하지 못한다.

**해결 방법**

- required 세 회귀의 모든 error-returning public 호출을 `if err != nil { t.Fatalf(...) }`로 즉시 검사한다.
- reprepare fixture를 distinct `[a,b,c,d]` payload로 바꾸고 partial confirm 뒤 exact `[c,d]`, post-snapshot append 배제를 content로 확인한다.
- fragment fixture는 `AsToolCallFragment`를 검사해 partial/full confirm의 exact `[B1,A2]` ID/arguments order와 이미 confirmed `[A1]` 비재방출을 확인한다.
- Korean fixture는 서로 다른 한글 rune sequence를 만들고 `want := string(runes[len(runes)-bound:])`와 look-behind content를 직접 비교한다. release content, defensive copy accessor 오류도 검사한다.
- required 세 함수 범위의 ignored-error 정적 검색이 출력 없이 끝나게 한다.

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

- [ ] `packages/go/streamgate/evidence_tail_test.go`: reprepare distinct suffix와 전 호출 error-checking
- [ ] `packages/go/streamgate/evidence_tail_test.go`: fragment exact public content/order와 전 호출 error-checking
- [ ] `packages/go/streamgate/evidence_tail_test.go`: 2/200/500 distinct Korean exact trailing suffix와 accessor error-checking

**테스트 작성**

- 기존 `TestEvidenceTailRepreparesOnlyUnconfirmedSnapshotSuffix`, `TestEvidenceTailFragmentCompletionPreservesOtherChannels`, `TestEvidenceTailPreservesExactKoreanSuffixContent`를 보강한다.
- 새 production defect subtest 외 별도 test file은 만들지 않는다.

**중간 검증**

```bash
/config/.local/bin/go test -count=1 ./packages/go/streamgate -run '^(TestEvidenceTailRepreparesOnlyUnconfirmedSnapshotSuffix|TestEvidenceTailFragmentCompletionPreservesOtherChannels|TestEvidenceTailPreservesExactKoreanSuffixContent)$'
```

```bash
if awk '
/^func TestEvidenceTailRepreparesOnlyUnconfirmedSnapshotSuffix/ { on = 1 }
/^func TestEvidenceTailFragmentCompletionCreatesSafePrefixEpoch/ { on = 0 }
/^func TestEvidenceTailFragmentCompletionPreservesOtherChannels/ { on = 1 }
/^func TestEvidenceTailTerminalGateConfiguredTrigger/ { on = 0 }
/^func TestEvidenceTailPreservesExactKoreanSuffixContent/ { on = 1 }
on { print FNR ":" $0 }
' packages/go/streamgate/evidence_tail_test.go |
	rg -n '(, _ :=|, _ =|^[0-9]+:[[:space:]]*tail\.(Append|ConfirmRelease|CompleteFragment)\()'; then
	exit 1
fi
```

기대 결과: exact content/order 회귀 PASS, required 함수의 ignored error search 출력 없음.

## 의존 관계 및 구현 순서

1. fragment cleanup을 absolute confirmed range 기준으로 고친다.
2. non-zero sequence cleanup 회귀를 먼저 고정한다.
3. reprepare/fragment/Korean 회귀의 ignored errors와 exact content assertion을 폐쇄한다.
4. fresh package/race/vet/hygiene와 transport setup evidence를 기록한다.

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `packages/go/streamgate/evidence_tail.go` | `REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-1` |
| `packages/go/streamgate/evidence_tail_test.go` | `REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-1`, `REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-2` |
| `agent-task/m-stream-evidence-gate-core/06+01_evidence_tail/CODE_REVIEW-local-G07.md` | 구현 체크, 변경/evidence와 실제 검증 출력 |

## 최종 검증

```bash
command -v go
readlink -f "$(command -v go)"
go version
go env GOROOT
/config/.local/bin/go test -count=1 ./packages/go/streamgate -run '^(TestEvidenceTailBindsOnlyReadyEpochSnapshots|TestEvidenceTailRepreparesOnlyUnconfirmedSnapshotSuffix|TestEvidenceTailRecoveryTransitions|TestEvidenceTailTerminalGateConfiguredTrigger|TestEvidenceTailFragmentCompletionCreatesSafePrefixEpoch|TestEvidenceTailFragmentCompletionPreservesOtherChannels|TestEvidenceTailBoundsAndCopiesEffectiveLookBehind|TestEvidenceTailRejectsInvalidReleaseLifecycle|TestEvidenceTailPreservesExactKoreanSuffixContent)$'
/config/.local/bin/go test -count=1 ./packages/go/streamgate -run '^Test(FilterHoldRequirement|EvidencePlan|EvidenceTail)'
/config/.local/bin/go test -race -count=1 ./packages/go/streamgate
/config/.local/bin/go vet ./packages/go/streamgate
gofmt -d packages/go/streamgate/evidence_tail.go packages/go/streamgate/evidence_tail_test.go
git diff --check -- packages/go/streamgate agent-task/m-stream-evidence-gate-core/06+01_evidence_tail
git status --short -- proto/gen/iop
if awk '
/^func TestEvidenceTailRepreparesOnlyUnconfirmedSnapshotSuffix/ { on = 1 }
/^func TestEvidenceTailFragmentCompletionCreatesSafePrefixEpoch/ { on = 0 }
/^func TestEvidenceTailFragmentCompletionPreservesOtherChannels/ { on = 1 }
/^func TestEvidenceTailTerminalGateConfiguredTrigger/ { on = 0 }
/^func TestEvidenceTailPreservesExactKoreanSuffixContent/ { on = 1 }
on { print FNR ":" $0 }
' packages/go/streamgate/evidence_tail_test.go |
	rg -n '(, _ :=|, _ =|^[0-9]+:[[:space:]]*tail\.(Append|ConfirmRelease|CompleteFragment)\()'; then
	exit 1
fi
! rg -n --sort path 't\.Skip|RegisterFragment|tokenToChannel' packages/go/streamgate/evidence_tail.go packages/go/streamgate/evidence_tail_test.go
/config/.local/bin/go test -count=1 ./apps/edge/internal/transport ./apps/node/internal/transport
```

기대 결과: focused/full/race/vet/gofmt/diff/proto/ignored-error/search는 PASS하고 cached test output은 없다. Transport unit은 PASS가 원칙이며, host GOROOT의 `crypto/internal/fips140cache` 누락이 지속되면 실제 setup failure와 host Go 복구 조건을 그대로 기록한다. 다른 toolchain으로 우회하지 않는다.

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