# Complete - m-provider-resource-admission-ownership-alignment/09+08_terminal_unavailable_outcome

## 완료 일시

2026-07-21

## 요약

Production provider-pool의 no-live-candidate outcome을 typed terminal unavailable로 연결하고 resolver fault와 capacity-full 대기를 분리했으며, 2회 루프 끝에 최종 PASS했다.

## 루프 이력

| Plan | Review | Verdict | 메모 |
|------|--------|---------|------|
| `plan_local_G06_0.log` | `code_review_local_G06_0.log` | FAIL | production resolver의 zero-live error가 terminal identity를 전달하지 못했고 신규 테스트가 실제 closure/capacity 분기를 증명하지 못해 Required 1건과 Nit 1건을 후속 보완으로 라우팅했다. |
| `plan_local_G06_1.log` | `code_review_local_G06_1.log` | PASS | typed production resolver identity, queue tri-state, production registry/store/catalog closure 회귀와 독립 검증이 모두 통과했다. |

## 구현/정리 내용

- provider-pool catalog가 유효한 상태에서 connected Node가 없거나 catalog-mapped provider의 연결 owner가 모두 사라진 경로만 `errProviderUnavailable`을 wrap하도록 정렬했다.
- queue pump가 `errors.Is(err, errProviderUnavailable)`를 terminal no-candidate로 낮추고, catalog/config resolver fault는 item과 deadline을 유지해 후속 재평가에서 회복하도록 했다.
- 실제 `Registry`, `NodeStore`, model catalog, provider-pool policy, `resolveQueueCandidatesClosure`를 사용해 disconnect 즉시 unavailable, full-candidate 대기, resolver-fault 회복을 검증했다.
- resolver outcome 주석과 테스트 이름을 non-terminal resolver error 대기 의미와 일치시켰다.

## 최종 검증

- `gofmt -d apps/edge/internal/service/model_queue_types.go apps/edge/internal/service/model_queue_admission.go apps/edge/internal/service/provider_resolution.go apps/edge/internal/service/model_queue_admission_test.go` - PASS; 출력 없음.
- `GOCACHE=/tmp/iop-gocache-terminal-unavailable-review2 go test -count=1 -v ./apps/edge/internal/service -run '^(TestProviderPoolQueuedDisconnectReturnsUnavailableImmediately|TestModelQueueStaysQueuedWhenAllCandidatesFull|TestProviderPoolQueuedResolverErrorStaysQueuedAndRecovers)$'` - PASS; 신규 production regression 3개 모두 실행·통과.
- `GOCACHE=/tmp/iop-gocache-terminal-unavailable-review2 go test -count=1 -race ./apps/edge/internal/service -run '^(TestProviderPoolQueuedDisconnectReturnsUnavailableImmediately|TestModelQueueStaysQueuedWhenAllCandidatesFull|TestProviderPoolQueuedResolverErrorStaysQueuedAndRecovers)$'` - PASS; `ok iop/apps/edge/internal/service 1.063s`, race warning 없음.
- `GOCACHE=/tmp/iop-gocache-terminal-unavailable-review2 go test -count=1 ./apps/edge/...` - PASS; Edge 전체 package 회귀 통과.
- `git diff --check -- apps/edge/internal/service/model_queue_types.go apps/edge/internal/service/model_queue_admission.go apps/edge/internal/service/provider_resolution.go apps/edge/internal/service/model_queue_admission_test.go` - PASS; 출력 없음.
- transport/event-drop full-cycle은 현 child의 소스 write set 밖이며 후속 split `13+09_disconnect_queue_settlement`의 검증 범위로 남겼다.

## 잔여 Nit

- 없음

## 후속 작업

- `13+09_disconnect_queue_settlement`: authoritative transport disconnect/event-drop 통합과 Milestone S13 전체 closure를 완성한다.
