<!-- task=m-provider-resource-admission-ownership-alignment/07+03_snapshot_source plan=6 tag=REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_PROVIDER_SNAPSHOT_SOURCE -->

# Code Review Reference - REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_PROVIDER_SNAPSHOT_SOURCE

> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
> The task is NOT complete until every implementation-owned section below is filled in.
> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving.
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
> If implementation is blocked by a selected Milestone `구현 잠금 > 결정 필요` item, fill `사용자 리뷰 요청` with linked evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`. Environment/secret/service blockers, generic scope changes, repeated failures, and evidence gaps that a follow-up agent can close are normal follow-up issues, not user-review blockers by themselves.
> Do not ask the user directly, present choices in chat, or call `request_user_input` during implementation; record only Milestone lock decisions in `사용자 리뷰 요청` and stop for code-review.
> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume.
> Follow the ownership table at the bottom of this file for which sections you own.

## 개요

date=2026-07-19
task=m-provider-resource-admission-ownership-alignment/07+03_snapshot_source, plan=6, tag=REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_PROVIDER_SNAPSHOT_SOURCE

## Roadmap Targets

- Milestone: `agent-roadmap/phase/operational-observability-provider-management/milestones/provider-resource-admission-ownership-alignment.md`
- Milestone link: [Milestone 문서](agent-roadmap/phase/operational-observability-provider-management/milestones/provider-resource-admission-ownership-alignment.md)
- Task ids:
  - `snapshot-source`: provider lease state와 live candidate pressure 기반 snapshot
- Completion mode: check-on-pass

## Archive Evidence Snapshot

- Prior task path: `agent-task/m-provider-resource-admission-ownership-alignment/07+03_snapshot_source`
- Archived plan: `agent-task/m-provider-resource-admission-ownership-alignment/07+03_snapshot_source/plan_local_G06_5.log`
- Archived review: `agent-task/m-provider-resource-admission-ownership-alignment/07+03_snapshot_source/code_review_local_G06_5.log`
- Verdict: FAIL
- Findings: Required 2, Suggested 0, Nit 0.
  - reader 결과를 받은 뒤 writer를 시작해 public reader와 runtime writer가 queue/service lock 경계에서 경합하지 않으며 queue lock 제거 회귀를 잡지 못한다.
  - reader/writer completion을 raw receive로 기다리고 waiter timeout을 성공 처리해 bounded failure cleanup과 terminal 검증이 없다.
- Reviewer cleanup: 호출자 없는 test helper 둘과 `buildSnapshotLocked`의 stale test 노출 설명은 비동작성 정리됐다.
- Affected files: `apps/edge/internal/service/status_provider_test.go`.
- Verification evidence:
  - reviewer fresh format/diff와 targeted snapshot suite, exact/concurrent 20회, race 5회, `go test -count=1 -timeout 120s ./apps/edge/...`는 PASS했다.
  - provider-pool preflight는 config check PASS 후 configured model/status endpoint 접근 불가로 BLOCKED(rc=3), evidence=`/tmp/iop-long-admission-smoke-provider-snapshot-review6b`.
- Roadmap carryover: `snapshot-source`는 public `ListNodeSnapshots()`가 queue lock을 실제 획득한 상태에서 writer를 대기시킨 deterministic old/new tuple과 bounded cleanup이 반복·race·Edge 전체 검증과 함께 통과할 때만 완료 대상으로 유지한다.
- Narrow reread allowed: 위 `plan_local_G06_5.log`, `code_review_local_G06_5.log` 두 파일만 필요 시 읽는다.

## 이 파일을 읽는 리뷰 에이전트에게

> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다.

각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다.

1. 판정을 append한다.
2. `CODE_REVIEW-local-G06.md` → `code_review_local_G06_6.log`, `PLAN-local-G06.md` → `plan_local_G06_6.log`로 아카이브한다.
3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/m-provider-resource-admission-ownership-alignment/07+03_snapshot_source/`로 이동한다. WARN/FAIL이면 user-review gate를 확인한 뒤 plan skill을 실행해 fresh routing된 다음 active pair를 만들거나 `USER_REVIEW.md`를 작성한다. `USER_REVIEW.md`가 연결된 Milestone 결정으로 완료/PASS 해소되면 code-review가 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log` 작성 후 archive 이동한다.
4. PASS이고 task group이 `m-<milestone-slug>`이면 완료 이벤트 메타데이터를 보고한다. roadmap 상태 체크와 `update-roadmap` 호출은 런타임 책임이다.
5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_PROVIDER_SNAPSHOT_SOURCE-1] Public reader lock acquisition과 writer handoff 강제 | [x] |
| [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_PROVIDER_SNAPSHOT_SOURCE-2] Bounded failure cleanup과 waiter terminal drain | [x] |

## 구현 체크리스트

- [x] `TestProviderSnapshotRuntimeRefreshIsOldOrNew`가 service write lock 아래 public `ListNodeSnapshots()` reader의 queue lock 획득을 bounded `TryLock` probe로 증명하고 writer를 그 queue lock 뒤에 대기시킨 다음 exact old `available/1/1`과 writer 완료 뒤 new `disabled/0/0`을 public surface에서 검증하며 `-count=20` 반복으로 재현되게 한다.
- [x] reader/writer/waiter의 모든 completion wait와 실패 cleanup을 explicit timeout으로 제한하고 waiter dispatch/error/terminal drain을 검증하며 provider별 exact concurrent assertion을 보존한 뒤 targeted·race·Edge 전체 검증과 provider-pool preflight 실제 출력을 기록한다.
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 코드리뷰 전용 체크리스트

> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.
> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다.

- [x] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
- [x] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다.
- [x] active `CODE_REVIEW-*-G??.md`를 `code_review_local_G06_6.log`로 아카이브한다.
- [x] active `PLAN-*-G??.md`를 `plan_local_G06_6.log`로 아카이브한다.
- [x] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인한다.
- [x] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다.
- [x] PASS이면 active task 디렉터리 `agent-task/m-provider-resource-admission-ownership-alignment/07+03_snapshot_source/`를 `agent-task/archive/YYYY/MM/m-provider-resource-admission-ownership-alignment/07+03_snapshot_source/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다.
- [x] PASS이고 task group이 `m-<milestone-slug>`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다.
- [x] PASS split 작업이면 이동 후 빈 active parent `agent-task/m-provider-resource-admission-ownership-alignment/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다.
- [ ] WARN/FAIL이고 user-review gate가 트리거되지 않았으면 plan skill을 실행하고 `finalize-task-routing`의 fresh 결과와 일치하는 다음 active `PLAN-local-GNN.md`와 `CODE_REVIEW-local-GNN.md`를 작성하며 `complete.log`를 작성하지 않는다.
- [ ] USER_REVIEW이면 `agent-ops/skills/common/code-review/templates/user-review-template.md` 기준으로 `USER_REVIEW.md`를 작성하고 active `PLAN-*.md`, `CODE_REVIEW-*.md`, `complete.log`를 남기지 않는다.
- [ ] USER_REVIEW가 연결된 Milestone 결정으로 완료/PASS 해소되면 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log`를 작성한 뒤 task directory를 archive로 이동한다.

## 계획 대비 변경 사항

없음. 계획의 Before/After 코드와 동일하게 구현했다.

## 주요 설계 결정

- `waitForQueueLockHeld` helper를 별도 test helper로 추출했다. main goroutine이 queue lock을 직접 보유하지 않은 상태에서 `TryLock` probe 실패로 reader의 queue lock 획득을 증명하는 책임이므로, `t.Fatal`을 호출하지 않고 error를 반환하는 순수 검증 함수로 구현했다.
- reader/writer completion은 각 실패 메시지가 구분되는 inline `select`와 explicit timeout으로 제한한다. 리뷰 중 호출자가 없던 `receiveSnapshotsWithin`과 `waitDoneWithin`은 비동작성 잔재로 제거했다.
- waiter drain에서 `waiterRes.run.Dispatch()` 후 `HandleRunLifecycleEvent`로 terminal event를 보낸다. original test에서는 waiter result만 receive하고 drain을 검증하지 않았지만, plan의 REVIEW-2 요구사항에 따라 resource/lease count가 0인지 terminal drain을 검증한다.

## 사용자 리뷰 요청

_기본값은 `없음`이다. 구현 중 새 결정이 필요해 보여도 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 이 섹션은 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 차단할 때만 채운다. 외부 환경/secret/서비스 준비, 검증 증거 공백, 반복 실패, 일반 범위 조정은 사용자 리뷰 요청이 아니며 `검증 결과`, `계획 대비 변경 사항`, 또는 code-review의 일반 follow-up plan으로 처리한다._

- 상태: 없음
- 사유 유형: 없음
- 연결 대상: 없음
- 결정 필요: 없음
- 차단 근거: 없음
- 실행한 검증/명령: 없음
- 자동 후속 불가 이유: 없음
- 재개 조건: 없음

## 리뷰어를 위한 체크포인트

- main goroutine이 queue lock을 직접 보유하지 않은 상태에서 service write lock으로 reader를 멈추고 bounded `TryLock` probe 실패로 public reader의 queue lock 획득을 증명하는지 본다.
- writer가 service lock 해제 전에 시작되어 reader가 보유한 queue lock 뒤에서 대기하며, reader old tuple과 writer 뒤 new tuple이 public surface에서 exact 검증되는지 본다.
- `ListNodeSnapshots()`가 queue lock을 잡지 않으면 probe가 성공/timeout으로 테스트를 실패시키는 구조인지 source invariant를 확인한다.
- reader/writer/waiter wait가 모두 explicit timeout을 가지며 failure path에서 service lock과 goroutine이 남지 않고 waiter terminal 뒤 resource/lease가 0으로 drain되는지 본다.
- concurrent storm의 shared/fallback provider presence, exact tuple, fallback 양 상태와 bounded first-error assertion이 보존됐는지 본다.
- 반복, targeted lifecycle, race, Edge 전체 출력과 preflight blocker evidence가 실제 명령 결과와 일치하는지 본다.

## 검증 결과

### REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_PROVIDER_SNAPSHOT_SOURCE-1 중간 검증

```bash
$ gofmt -d apps/edge/internal/service/status_provider_test.go
(no output)

$ GOCACHE=/tmp/iop-go-cache-provider-snapshot-public-reader-followup6 go test -list '^TestProviderSnapshotRuntimeRefreshIsOldOrNew$' ./apps/edge/internal/service | rg --fixed-strings 'TestProviderSnapshotRuntimeRefreshIsOldOrNew'
TestProviderSnapshotRuntimeRefreshIsOldOrNew

$ GOCACHE=/tmp/iop-go-cache-provider-snapshot-public-reader-followup6 go test -count=20 -timeout 60s ./apps/edge/internal/service -run '^TestProviderSnapshotRuntimeRefreshIsOldOrNew$'
ok  	ipop/apps/edge/internal/service	0.257s
```

### REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_PROVIDER_SNAPSHOT_SOURCE-2 중간 검증

```bash
$ git diff --check -- apps/edge/internal/service/status_provider_test.go
(no output)

$ rg --sort path -n 'buildSnapshotLocked\(' apps/edge/internal/service/status_provider_test.go
NONE FOUND (PASS)

$ GOCACHE=/tmp/iop-go-cache-provider-snapshot-public-reader-followup6 go test -count=20 -timeout 60s ./apps/edge/internal/service -run '^TestProviderSnapshot(RuntimeRefreshIsOldOrNew|ConcurrentRefreshPressureUsesLiveCandidates)$'
ok  	ipop/apps/edge/internal/service	6.765s

$ GOCACHE=/tmp/iop-go-cache-provider-snapshot-public-reader-followup6 go test -race -count=5 -timeout 60s ./apps/edge/internal/service -run '^TestProviderSnapshot(RuntimeRefreshIsOldOrNew|LiveCandidatePressureFollowsRefreshAcrossModelGroups|ConcurrentRefreshPressureUsesLiveCandidates|QueuedCountsCandidatePressureAcrossModelGroups)$'
ok  	ipop/apps/edge/internal/service	2.896s
```

### 최종 검증

```bash
$ gofmt -d apps/edge/internal/service/status_provider_test.go
(no output)

$ git diff --check -- apps/edge/internal/service/status_provider_test.go
(no output)

$ rg --sort path -n 'buildSnapshotLocked\(' apps/edge/internal/service/status_provider_test.go
NONE FOUND (PASS)

$ GOCACHE=/tmp/iop-go-cache-provider-snapshot-public-reader-followup6 go test -list '^TestProviderSnapshotRuntimeRefreshIsOldOrNew$' ./apps/edge/internal/service | rg --fixed-strings 'TestProviderSnapshotRuntimeRefreshIsOldOrNew'
TestProviderSnapshotRuntimeRefreshIsOldOrNew

$ GOCACHE=/tmp/iop-go-cache-provider-snapshot-public-reader-followup6 go test -count=20 -timeout 60s ./apps/edge/internal/service -run '^TestProviderSnapshot(RuntimeRefreshIsOldOrNew|ConcurrentRefreshPressureUsesLiveCandidates)$'
ok  	ipop/apps/edge/internal/service	6.765s

$ GOCACHE=/tmp/iop-go-cache-provider-snapshot-public-reader-followup6 go test -count=1 ./apps/edge/internal/service -run '^TestProviderSnapshot(ResolverErrorDoesNotUseStaleCandidate|RuntimeRefreshIsOldOrNew|LiveCandidatePressureFollowsRefreshAcrossModelGroups|ConcurrentRefreshPressureUsesLiveCandidates|QueuedCountsCandidatePressureAcrossModelGroups|ReadsResourceState|IgnoresLegacyFallbackState)$'
ok  	ipop/apps/edge/internal/service	0.327s

$ GOCACHE=/tmp/iop-go-cache-provider-snapshot-public-reader-followup6 go test -race -count=5 -timeout 60s ./apps/edge/internal/service -run '^TestProviderSnapshot(RuntimeRefreshIsOldOrNew|LiveCandidatePressureFollowsRefreshAcrossModelGroups|ConcurrentRefreshPressureUsesLiveCandidates|QueuedCountsCandidatePressureAcrossModelGroups)$'
ok  	ipop/apps/edge/internal/service	2.676s

$ GOCACHE=/tmp/iop-go-cache-provider-snapshot-public-reader-followup6 go test -count=1 -timeout 120s ./apps/edge/...
ok  	ipop/apps/edge/cmd/edge	0.142s
ok  	ipop/apps/edge/internal/bootstrap	0.401s
ok  	ipop/apps/edge/internal/configrefresh	0.041s
ok  	ipop/apps/edge/internal/controlplane	4.522s
ok  	ipop/apps/edge/internal/edgecmd	0.045s
ok  	ipop/apps/edge/internal/edgevalidate	0.006s
ok  	ipop/apps/edge/internal/events	0.007s
ok  	ipop/apps/edge/internal/input	0.088s
ok  	ipop/apps/edge/internal/input/a2a	0.019s
ok  	ipop/apps/edge/internal/node	0.012s
ok  	ipop/apps/edge/internal/openai	7.081s
ok  	ipop/apps/edge/internal/opsconsole	0.041s
ok  	ipop/apps/edge/internal/service	3.765s
ok  	ipop/apps/edge/internal/transport	2.291s

$ GOCACHE=/tmp/iop-go-cache-provider-snapshot-public-reader-followup6 scripts/e2e-long-context-admission-smoke.sh --preflight --out-dir /tmp/iop-long-admission-smoke-provider-snapshot-public-reader-followup6
OK configs/edge.yaml
config check OK
[long-admission-smoke] endpoint reachability: http://toki-labs.com:18083/v1/models
[long-admission-smoke]   BLOCKER: /models unreachable. exact command:
[long-admission-smoke]     curl -fsS --connect-timeout 10 http://toki-labs.com:18083/v1/models
[long-admission-smoke] status reachability: http://127.0.0.1:18001/edges/edge-toki-labs-dev/status
[long-admission-smoke]   BLOCKER: status unreachable. exact command:
[long-admission-smoke]     curl -fsS --connect-timeout 10 http://127.0.0.1:18001/edges/edge-toki-labs-dev/status
[long-admission-smoke] expected baseline: normal_capacity_total=9 long_slot_total=4
[long-admission-smoke] === PREFLIGHT BLOCKED (see out-dir; blockers are verification blockers, not user-review) ===
[long-admission-smoke] done rc=3 evidence=/tmp/iop-long-admission-smoke-provider-snapshot-public-reader-followup6
```

All format/diff/direct-call/exact existence/fresh deterministic/concurrent/targeted/race/Edge full tests PASS. Preflight BLOCKED (rc=3) due to external endpoint unavailability — configured model/status endpoint unreachable. This is a separate `capacity-smoke` Task responsibility and does not block test-only implementation decisions.

---

> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?**
> If anything is blank, go back and fill it in before saving this file.
> Leave review-agent-only sections unchanged.

## 섹션 소유권

| Section | Owner | Note |
|---------|-------|------|
| Header comment, 개요, 리뷰 에이전트 지시 | Fixed at stub creation | Implementing agent must not modify or execute these (archive, complete.log, and task-directory archive move are review-agent only) |
| Roadmap Targets | Fixed at stub creation from plan when present | Implementing agent must not modify; code-review copies it into `complete.log` as `Roadmap Completion` only on PASS |
| Archive Evidence Snapshot | Fixed at stub creation from plan when present | Implementing agent uses it as default prior-loop context; read only the specific archive files cited there when more detail is required |
| Agent UI Completion | Mixed | Present only for plan-required agent-ui code work; implementing agent fills actual evidence, review agent applies `구현됨` status/evidence update on PASS and copies the section into `complete.log` |
| 구현 항목별 완료 여부 (item names) | Fixed at stub creation | Implementing agent checks `[ ]` → `[x]` only |
| 구현 체크리스트 (item text/order) | Fixed at stub creation from plan | Implementing agent checks `[ ]` → `[x]` only; final checkbox is mandatory before saving |
| 코드리뷰 전용 체크리스트 | Review agent only | Implementing agent must not modify or check this section |
| 계획 대비 변경 사항, 주요 설계 결정 | Implementing agent | Replace placeholder text with actual content |
| 사용자 리뷰 요청 | Implementing agent | Keep `상태: 없음` unless a selected Milestone `구현 잠금 > 결정 필요` item blocks implementation; do not ask the user directly during implementation; environment/secret/service blockers, generic scope changes, and evidence gaps are not user-review requests |
| 리뷰어를 위한 체크포인트 | Fixed at stub creation | Pre-filled from plan |
| 검증 결과 (section headings + commands) | Fixed at stub creation | Implementing agent fills in command output only; command changes require a `계획 대비 변경 사항` entry |
| 코드리뷰 결과 | Review agent appends | Not included in stub |

## 코드리뷰 결과

- 종합 판정: PASS
- 차원별 평가:
  - correctness: Pass
  - completeness: Pass
  - test coverage: Pass
  - API contract: Pass
  - code quality: Pass
  - implementation deviation: Pass
  - verification trust: Pass
  - spec conformance: Pass
- 발견된 문제: 없음
- 다음 단계: PASS — `complete.log` 작성 후 task directory를 월별 archive로 이동하고 Milestone runtime completion metadata를 보고한다.
