<!-- task=m-proto-socket-infrastructure-communication-rail/01_core_endpoint plan=2 tag=REVIEW2_CORE-ENDPOINT -->

# Plan - REVIEW2_CORE-ENDPOINT

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

구현 완료의 마지막 단계는 active `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채우는 것이다. 검증 명령을 실행하고 실제 stdout/stderr를 남긴 뒤 active 파일을 그대로 둔 채 리뷰 준비 상태를 보고한다. 최종 판정, log rename, `complete.log`, archive 이동은 code-review-skill 전용이다.

구현 중 사용자만 결정할 수 있는 사항, 외부 환경 준비, 또는 계획 범위 충돌로 진행할 수 없으면 review stub의 `사용자 리뷰 요청` 섹션에 정확한 결정 필요 사항, 근거, 실행한 명령과 출력, 재개 조건을 채우고 중단한다. 구현 에이전트는 `USER_REVIEW.md`, archive log, `complete.log`를 직접 만들지 않는다.

## 배경

`code_review_cloud_G08_1.log`는 follow-up 구현이 시작되지 않은 상태에서 리뷰가 요청되어 `FAIL` 처리되었다. 이 계획은 `code_review_cloud_G08_0.log`와 `code_review_cloud_G08_1.log`의 Required 항목을 실제 코드와 active review stub까지 닫는 좁은 재시도 계획이다. task channel 구현, client rail, 추가 protocol feature는 범위 밖이다.

## 사용자 리뷰 요청 흐름

구현 중 차단 사항은 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 이 섹션은 `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` 내용을 사용하며, code-review가 검증한 뒤 실제 `USER_REVIEW.md` 작성 여부를 결정한다.

## 분석 결과

### 읽은 파일

- `agent-task/m-proto-socket-infrastructure-communication-rail/01_core_endpoint/code_review_cloud_G08_0.log`
- `agent-task/m-proto-socket-infrastructure-communication-rail/01_core_endpoint/code_review_cloud_G08_1.log`
- `agent-task/m-proto-socket-infrastructure-communication-rail/01_core_endpoint/plan_cloud_G08_1.log`
- `services/core/go.mod`
- `services/core/internal/protosocket/envelope.go`
- `services/core/internal/http/middleware_test.go`
- `services/core/internal/config/config.go`
- `packages/contracts/notes/flutter-core-api-candidates.md`

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

- module resolution: `services/core/go.mod` still uses a zero pseudo-version plus repo-external sibling `replace`.
- envelope contract: `EnvelopeError` still lacks the `retryable` field from the contract note.
- route exposure: unauthenticated `/proto-socket` is tested, but authenticated handler reachability is not.
- formatting: `services/core/internal/config/config.go` remains visibly non-gofmt formatted.
- review readiness: previous active `CODE_REVIEW-cloud-G08.md` was left unchecked and placeholder-filled, so verification evidence was absent.

### 심볼 참조

- 제거/rename 심볼 없음.
- `EnvelopeError` field addition affects literals and assertions in `services/core/internal/protosocket/envelope.go`, `dispatcher.go`, `server.go`, `envelope_test.go`, `server_test.go`.

### 분할 판단

Split decision policy를 평가했다. 이 작업은 같은 split subtask `01_core_endpoint`의 incomplete follow-up 재시도이며, 남은 Required 항목이 한 endpoint foundation의 dependency/contract/test/readiness 회복에 묶인다. 새 sibling subtask를 만들지 않는다.

### 범위 결정 근거

- `02+01_task_channels`는 시작하지 않는다.
- `apps/client/**`와 `../proto-socket/**`는 수정하지 않는다.
- 새로운 action handler, fanout, origin policy, transport feature는 추가하지 않는다.
- active review stub 작성은 구현 완료 조건이므로 범위에 포함한다.

### 빌드 등급

`cloud-G08`. 이전 cloud-G08 protocol/auth/contract follow-up이고 verification trust 복구가 포함된다.

## 구현 체크리스트

- [ ] `services/core`의 proto-socket dependency에서 repo-external `replace`와 zero pseudo-version을 제거하고 publish된 module version으로 재정리한다.
- [ ] `EnvelopeError`의 `retryable` contract를 구현하고 envelope/error 테스트를 갱신한다.
- [ ] `/proto-socket` authenticated route exposure test를 추가한다.
- [ ] `services/core/internal/config/config.go`를 `gofmt`로 정리한다.
- [ ] 허용된 비로컬 테스트 환경에서 module tidy, focused Go tests, full Go tests, formatting/diff 검증을 `-count=1` 기준으로 실행하고 실제 출력을 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 의존 관계 및 구현 순서

이 subtask는 기존 `01_core_endpoint`의 follow-up 재시도다. 같은 디렉터리 안에서 현재 Required 항목을 닫고, PASS 전까지 `02+01_task_channels`는 시작하지 않는다.

### [REVIEW2_CORE-ENDPOINT-1] Fix proto-socket module requirement

#### 문제

`services/core/go.mod:6`은 `git.toki-labs.com/toki/proto-socket/go v0.0.0-00010101000000-000000000000`를 require하고 `services/core/go.mod:35`는 `../../../proto-socket/go`를 replace한다. 이는 repo 밖 sibling checkout에 의존해 CI/배포 재현성을 깨뜨린다.

#### 해결 방법

`../proto-socket/examples/go-module-consumer/go.mod`가 사용한 publish된 pseudo-version `v0.0.0-20260501220005-284b66a22300`로 require를 고정하고 repo-external `replace`를 제거한다. 허용된 비로컬 환경에서 private module fetch가 실패하면 active review stub의 `사용자 리뷰 요청`에 command output과 resume condition을 남기고 중단한다.

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

- [ ] `services/core/go.mod`: zero pseudo-version과 `replace` 제거.
- [ ] `services/core/go.sum`: `go mod tidy` 결과 반영.

#### 테스트 작성

- 작성하지 않음. `go mod tidy`와 `go list -m` 검증으로 판단한다.

#### 중간 검증

```bash
cd services/core && go mod tidy
cd services/core && go list -m git.toki-labs.com/toki/proto-socket/go
```

예상 결과: repo-external `replace` 없이 publish된 proto-socket module version이 출력된다.

### [REVIEW2_CORE-ENDPOINT-2] Implement retryable error envelope field

#### 문제

`packages/contracts/notes/flutter-core-api-candidates.md`의 error 후보는 `retryable`을 포함하지만 `services/core/internal/protosocket/envelope.go:25`의 `EnvelopeError`는 이를 표현하지 않는다.

#### 해결 방법

`EnvelopeError`에 `Retryable bool`을 추가하고 `ToStruct`가 `retryable`을 항상 포함하도록 하며 `EnvelopeFromStruct`가 bool 값을 복원하도록 한다. Tests must assert round-trip and unsupported-action response both preserve `retryable=false`.

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

- [ ] `services/core/internal/protosocket/envelope.go`: `Retryable bool`과 변환 로직 추가.
- [ ] `services/core/internal/protosocket/envelope_test.go`: round-trip assertion 추가.
- [ ] `services/core/internal/protosocket/server_test.go`: unsupported action `Retryable == false` assertion 추가.

#### 테스트 작성

- 작성: `TestEnvelopeStructRoundTrip` retryable assertion.
- 작성: `TestServerRespondsWithErrorEnvelopeForUnsupportedAction` retryable assertion.

#### 중간 검증

```bash
cd services/core && go test -count=1 ./internal/protosocket
```

예상 결과: proto-socket focused tests PASS.

### [REVIEW2_CORE-ENDPOINT-3] Add authenticated route exposure assertion

#### 문제

`services/core/internal/http/middleware_test.go:46` only checks `/proto-socket` without credentials returns `401`. It does not prove valid Basic Auth reaches the mounted handler.

#### 해결 방법

Add a valid Basic Auth request to `/proto-socket` in the router test and assert `http.StatusOK` from the mock handler.

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

- [ ] `services/core/internal/http/middleware_test.go`: authenticated `/proto-socket` assertion 추가.

#### 테스트 작성

- 작성: `SetBasicAuth("nomadcode", "secret")` request -> `200`.

#### 중간 검증

```bash
cd services/core && go test -count=1 ./internal/http
```

예상 결과: router/auth tests PASS.

### [REVIEW2_CORE-ENDPOINT-4] Restore formatting and review readiness

#### 문제

`services/core/internal/config/config.go:30` is not gofmt-formatted, and the prior active review stub was submitted with unchecked checklist and placeholder verification output.

#### 해결 방법

Run gofmt on `services/core/internal/config/config.go`. After all code changes and verification are complete, fill this active `CODE_REVIEW-cloud-G08.md` implementation table, checklist, design notes, plan deviations, and exact command stdout/stderr.

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

- [ ] `services/core/internal/config/config.go`: gofmt 적용.
- [ ] `agent-task/m-proto-socket-infrastructure-communication-rail/01_core_endpoint/CODE_REVIEW-cloud-G08.md`: 구현 에이전트 소유 섹션 작성.

#### 테스트 작성

- 작성하지 않음. formatting and review artifact readiness check다.

#### 중간 검증

```bash
gofmt -l services/core/internal/config/config.go
```

예상 결과: 출력 없음.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `services/core/go.mod` | REVIEW2_CORE-ENDPOINT-1 |
| `services/core/go.sum` | REVIEW2_CORE-ENDPOINT-1 |
| `services/core/internal/protosocket/envelope.go` | REVIEW2_CORE-ENDPOINT-2 |
| `services/core/internal/protosocket/envelope_test.go` | REVIEW2_CORE-ENDPOINT-2 |
| `services/core/internal/protosocket/server_test.go` | REVIEW2_CORE-ENDPOINT-2 |
| `services/core/internal/http/middleware_test.go` | REVIEW2_CORE-ENDPOINT-3 |
| `services/core/internal/config/config.go` | REVIEW2_CORE-ENDPOINT-4 |
| `agent-task/m-proto-socket-infrastructure-communication-rail/01_core_endpoint/CODE_REVIEW-cloud-G08.md` | REVIEW2_CORE-ENDPOINT-4 |

## 최종 검증

로컬 테스트 실행은 `agent-test/local/rules.md`에 따라 금지다. 구현 에이전트는 허용된 비로컬 테스트 환경에서 아래 명령을 그대로 실행한다. Go test cache output은 허용하지 않으며 `-count=1`을 유지한다.

```bash
cd services/core && go mod tidy
```

예상 결과: repo-external `replace` 없이 dependency graph 정리 성공.

```bash
cd services/core && go list -m git.toki-labs.com/toki/proto-socket/go
```

예상 결과: publish된 proto-socket module version 출력.

```bash
cd services/core && go test -count=1 ./internal/config ./internal/protosocket ./internal/http
```

예상 결과: focused tests PASS.

```bash
cd services/core && go test -count=1 ./...
```

예상 결과: Core 전체 package PASS.

```bash
gofmt -l services/core/internal/config/config.go services/core/internal/protosocket/envelope.go services/core/internal/protosocket/envelope_test.go services/core/internal/protosocket/server_test.go services/core/internal/http/middleware_test.go
```

예상 결과: 출력 없음.

```bash
git diff --check
```

예상 결과: whitespace error 없음.

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
